From b5a877a3fe152d1433aa19a0311f30fb360ca554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Mon, 19 Jan 2026 22:05:47 +0000 Subject: [PATCH 01/58] Translated using Weblate (Czech) Currently translated at 99.9% (1003 of 1004 strings) Translation: 86Box/86Box Translate-URL: https://weblate.86box.net/projects/86box/86box/cs/ --- src/qt/languages/cs-CZ.po | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index bed51f2610..7dd135138e 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2026-01-02 21:56+0000\n" +"PO-Revision-Date: 2026-01-20 03:58+0000\n" "Last-Translator: David Hrdlička \n" "Language-Team: Czech \n" "Language: cs-CZ\n" @@ -3019,7 +3019,8 @@ msgid "&Fast forward" msgstr "" msgid "Fast forward" -msgstr "" +msgstr "Zrychlit" msgid "To change the system directory, stop all running machines." msgstr "" +"Před změnou systémového adresáře nejprve zastavte všechny běžící počítače." From 89eff9b33f044c186b04064e15c8b18431dee077 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 20 Jan 2026 16:22:04 +0100 Subject: [PATCH 02/58] CPU: 40 MHz bus speed means 20 MHz PCI speed, per real hardware report by Efflixi. --- src/cpu/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 8d00da512c..6e675acc89 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1897,7 +1897,7 @@ cpu_set_pci_speed(int speed) { if (speed) cpu_pci_speed = speed; - else if (cpu_busspeed < 42500000) + else if (cpu_busspeed < 40000000) cpu_pci_speed = cpu_busspeed; else if (cpu_busspeed < 84000000) cpu_pci_speed = cpu_busspeed / 2; From 275604db61bbab216a4a33e4a85faff9ee84c577 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Jan 2026 03:21:14 +0100 Subject: [PATCH 03/58] IDE: Some fixes - it now works on the Intel Monsoon. --- src/disk/hdc_ide.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 7b2b768162..c63bb9d6e9 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1603,10 +1603,12 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) int ch; int bad = 0; int reset = 0; + int prev; ch = dev->cur_dev; ide = ide_drives[ch]; ide_other = ide_drives[ch ^ 1]; + prev = ide->command; ide_log("[%04X:%08X] ide_writeb(%04X, %02X, %08X)\n", CS, cpu_state.pc, addr, val, priv); @@ -1649,37 +1651,31 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) break; case 0x4: /* Cylinder low */ - if (ide->type & IDE_SHADOW) - break; - - if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + if (!(ide->type & IDE_SHADOW) && !(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { ide->tf->cylinder = (ide->tf->cylinder & 0xff00) | val; ide->lba_addr = (ide->lba_addr & 0xfff00ff) | (val << 8); } - if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + if (!(ide_other->type & IDE_SHADOW) && !(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff00) | val; ide_other->lba_addr = (ide_other->lba_addr & 0xfff00ff) | (val << 8); } break; case 0x5: /* Cylinder high */ - if (ide->type & IDE_SHADOW) - break; - - if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + if (!(ide->type & IDE_SHADOW) && !(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { ide->tf->cylinder = (ide->tf->cylinder & 0xff) | (val << 8); ide->lba_addr = (ide->lba_addr & 0xf00ffff) | (val << 16); } - if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + if (!(ide_other->type & IDE_SHADOW) && !(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff) | (val << 8); ide_other->lba_addr = (ide_other->lba_addr & 0xf00ffff) | (val << 16); } break; case 0x6: /* Drive/Head */ - if (ch != ((val >> 4) & 1) + (ide->board << 1)) { + if (ch != (((val >> 4) & 1) + (ide->board << 1))) { if (!ide->reset && !ide_other->reset && ide->irqstat) { ide_irq_lower(ide); ide->irqstat = 1; @@ -1786,7 +1782,13 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus_type, 1); uint32_t sec_count; double wait_time; - if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { + if ((val == WIN_READ) && (prev == WIN_SETIDLE1)) { + /* Do the callback instantly - this happens on the Intel Monsoon. */ + (void) hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + ide->do_initial_read = 1; + ide_callback(ide); + break; + } else if ((val == WIN_READ_DMA) || (val == WIN_READ_DMA_ALT)) { /* TODO: Make DMA timing more accurate. */ sec_count = ide->tf->secount ? ide->tf->secount : 256; double seek_time = hdd_timing_read(&hdd[ide->hdd_num], @@ -2346,6 +2348,7 @@ ide_callback(void *priv) case WIN_READ: case WIN_READ_NORETRY: + ide_log("IDE(%d) read(%d,%d,%d)\n", ide->channel, ide->tf->cylinder, ide->tf->head, ide->tf->sector); if (ide->type == IDE_ATAPI) { ide_set_signature(ide); err = ABRT_ERR; From 57c7e6114c0ec721043da390412977392c41c349 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Jan 2026 05:40:27 +0100 Subject: [PATCH 04/58] VLSI VL82c480: Re-enable the A20 stuff. --- src/chipset/vl82c480.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/chipset/vl82c480.c b/src/chipset/vl82c480.c index 2ab17eadd0..cf36827542 100644 --- a/src/chipset/vl82c480.c +++ b/src/chipset/vl82c480.c @@ -154,13 +154,10 @@ vl82c480_write(uint16_t addr, uint8_t val, void *priv) } break; -/* TODO: This is actually Fast A20 disable. */ -#if 0 case 0xee: mem_a20_alt = 0x00; mem_a20_recalc(); break; -#endif default: break; @@ -184,13 +181,10 @@ vl82c480_read(uint16_t addr, void *priv) ret = dev->regs[dev->idx]; break; -/* TODO: This is actually Fast A20 enable. */ -#if 0 case 0xee: mem_a20_alt = 0x02; mem_a20_recalc(); break; -#endif case 0xef: softresetx86(); From df39399513793e34ce2320af81b6874670297c6a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Jan 2026 06:11:46 +0100 Subject: [PATCH 05/58] A small IDE fix from win2kgamer. --- src/disk/hdc_ide.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index c63bb9d6e9..56548766ab 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1717,7 +1717,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) case 0x7: /* Command register */ if ((ide->tf->atastat & (BSY_STAT | DRQ_STAT)) && - ((val != WIN_SRST) || (ide->type != IDE_ATAPI))) + ((val != WIN_SRST) || (ide->type != IDE_ATAPI)) && + ((val != WIN_VERIFY) || (prev != WIN_IDENTIFY))) break; if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS))) From 7a462af5d10f6a15a5a259f9605279ff901afe6a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 21 Jan 2026 07:26:15 +0100 Subject: [PATCH 06/58] AT NVR: Some changes in preparation for the MS-5156. --- src/nvr_at.c | 45 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/src/nvr_at.c b/src/nvr_at.c index 07588fb01b..8283c08b0e 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -289,21 +289,21 @@ #define RTC_REGS 14 /* number of registers */ -#define FLAG_NO_NMI 0x01 -#define FLAG_AMI_1992_HACK 0x02 -#define FLAG_AMI_1994_HACK 0x04 -#define FLAG_AMI_1995_HACK 0x08 -#define FLAG_P6RP4_HACK 0x10 -#define FLAG_PIIX4 0x20 -#define FLAG_MULTI_BANK 0x40 -#define FLAG_MARTIN_HACK 0x80 +#define FLAG_NO_NMI 0x001 +#define FLAG_AMI_1992_HACK 0x002 +#define FLAG_AMI_1994_HACK 0x004 +#define FLAG_AMI_1995_HACK 0x008 +#define FLAG_AMI_1999_HACK 0x010 +#define FLAG_P6RP4_HACK 0x020 +#define FLAG_PIIX4 0x040 +#define FLAG_MULTI_BANK 0x080 +#define FLAG_MARTIN_HACK 0x100 typedef struct local_t { int8_t stat; uint8_t cent; uint8_t def; - uint8_t flags; uint8_t read_addr; uint8_t wp_0d; uint8_t wp_32; @@ -317,6 +317,8 @@ typedef struct local_t { int16_t count; int16_t state; + uint16_t flags; + uint16_t addr[8]; int32_t smi_enable; @@ -576,6 +578,8 @@ nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) nvr->is_new = 0; if ((reg == 0x52) && (local->flags & FLAG_AMI_1995_HACK)) nvr->is_new = 0; + if ((reg == 0x55) && (local->flags & FLAG_AMI_1999_HACK)) + nvr->is_new = 0; if ((reg >= 0x38) && (reg <= 0x3f) && local->wp[0]) return; if ((reg >= 0xb8) && (reg <= 0xbf) && local->wp[1]) @@ -825,6 +829,20 @@ nvr_read(uint16_t addr, void *priv) ret = checksum >> 8; else ret = checksum & 0xff; + } else if (!nvr->is_new && (local->flags & FLAG_AMI_1999_HACK)) { + /* The checksum at 3E-3F is for 37-3D and 40-73. */ + for (i = 0x37; i <= 0x3d; i++) + checksum += nvr->regs[i]; + for (i = 0x40; i <= 0x73; i++) { + if (i == 0x55) + checksum += (nvr->regs[i] & 0xfc); + else + checksum += nvr->regs[i]; + } + if (local->addr[addr_id] == 0x3e) + ret = checksum >> 8; + else + ret = checksum & 0xff; } else if (!nvr->is_new && (local->flags & FLAG_P6RP4_HACK)) { /* The checksum at 3E-3F is for 37-3D and 40-51. */ for (i = 0x37; i <= 0x3d; i++) @@ -857,6 +875,13 @@ nvr_read(uint16_t addr, void *priv) ret = nvr->regs[local->addr[addr_id]]; break; + case 0x55: + if (!nvr->is_new && (local->flags & FLAG_AMI_1999_HACK)) + ret = nvr->regs[local->addr[addr_id]] & 0xfc; + else + ret = nvr->regs[local->addr[addr_id]]; + break; + default: if (!(local->lock[local->addr[addr_id]] & 0x02)) ret = nvr->regs[local->addr[addr_id]]; @@ -1174,7 +1199,7 @@ nvr_at_init(const device_t *info) break; case 8: /* Epson Equity LT */ if ((info->local & 0x1f) == 0x18) { - local->flags |= (FLAG_PIIX4 | FLAG_AMI_1995_HACK); + local->flags |= (FLAG_PIIX4 | FLAG_AMI_1999_HACK); local->def = 0x00; nvr->irq = 8; local->cent = RTC_CENTURY_AT; From 5a985e137fc788fff29b4199a0062147a503bebb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Hrdli=C4=8Dka?= Date: Tue, 20 Jan 2026 09:18:35 +0000 Subject: [PATCH 07/58] Translated using Weblate (Czech) Currently translated at 100.0% (1004 of 1004 strings) Translation: 86Box/86Box Translate-URL: https://weblate.86box.net/projects/86box/86box/cs/ --- src/qt/languages/cs-CZ.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 7dd135138e..5e89f736ac 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2026-01-20 03:58+0000\n" +"PO-Revision-Date: 2026-01-21 07:40+0000\n" "Last-Translator: David Hrdlička \n" "Language-Team: Czech \n" "Language: cs-CZ\n" @@ -3016,7 +3016,7 @@ msgid "&Allow recompilation" msgstr "&Povolit rekompilaci" msgid "&Fast forward" -msgstr "" +msgstr "&Zrychlit" msgid "Fast forward" msgstr "Zrychlit" From 6b014f6c87aa04ad756488b8d3de0d63110a572f Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Wed, 21 Jan 2026 20:55:52 +0600 Subject: [PATCH 08/58] Do RGB correction only on Qt5 --- src/qt/qt_vulkanwindowrenderer.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index c27d382a50..52d42ebf4e 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -900,7 +900,11 @@ VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) strcat(path, fn); QImage image = this->grab(); +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) + image.save(path, "png"); +#else image.rgbSwapped().save(path, "png"); +#endif monitors[r_monitor_index].mon_screenshots--; } if (monitors[r_monitor_index].mon_screenshots_clipboard) { From f72da2a077dc7c73e240c5f6bd22d28dce9a2af1 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Wed, 21 Jan 2026 16:10:18 -0300 Subject: [PATCH 09/58] Jenkins: Update appimage-builder setuptools manually to fix build --- .ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index a5b20f2aa6..6dd573cb60 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -1257,7 +1257,7 @@ EOF then rm -rf "$cache_dir/appimage-builder-"* # remove old versions python3 -m venv "$appimage_builder_dir" # venv to solve some Debian setuptools headaches - "$appimage_builder_dir/bin/pip" install -U "git+https://github.com/AppImageCrafters/appimage-builder.git@$appimage_builder_commit" + "$appimage_builder_dir/bin/pip" install -U "git+https://github.com/AppImageCrafters/appimage-builder.git@$appimage_builder_commit" 'setuptools<81' fi # Symlink appimage-builder global cache directory. From 97e1f5bd3998afbcde0511ba1698218934f601a8 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 21 Jan 2026 16:34:01 -0300 Subject: [PATCH 10/58] Jenkins: Enable DLS support and remove extraneous features from the AppImage FluidSynth --- .ci/AppImageBuilder.yml | 1 + .ci/build.sh | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 61bbcba95e..ad0bc904c6 100644 --- a/.ci/AppImageBuilder.yml +++ b/.ci/AppImageBuilder.yml @@ -48,6 +48,7 @@ AppDir: - libfreetype6 - libgomp1 - libgs9 + - libinstpatch-1.0-2 - libpng16-16 - libqt5core5a # if QT:BOOL=ON - libqt5gui5 # if QT:BOOL=ON diff --git a/.ci/build.sh b/.ci/build.sh index 6dd573cb60..2262d31dcc 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -698,7 +698,7 @@ else # ...and the ones we do want listed. Non-dev packages fill missing spots on the list. libpkgs="" longest_libpkg=0 - for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev libserialport-dev + for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev libserialport-dev libinstpatch-dev do libpkgs="$libpkgs $pkg:$arch_deb" length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c) @@ -1081,7 +1081,8 @@ else wget -qO - https://github.com/FluidSynth/fluidsynth/archive/refs/tags/v2.3.0.tar.gz | tar zxf - -C "$cache_dir" || rm -rf "$prefix" fi prefix_build="$prefix/build-$arch_deb" - cmake -G Ninja -D enable-dbus=OFF -D enable-jack=OFF -D enable-oss=OFF -D enable-sdl2=OFF -D enable-pulseaudio=OFF -D enable-pipewire=OFF -D enable-alsa=OFF \ + cmake -G Ninja -D enable-jack=OFF -D enable-oss=OFF -D enable-sdl2=OFF -D enable-pulseaudio=OFF -D enable-pipewire=OFF -D enable-alsa=OFF \ + -D enable-aufile=OFF -D enable-dbus=OFF -D enable-network=OFF -D enable-ipv6=OFF \ -D "CMAKE_TOOLCHAIN_FILE=$toolchain_file_libs" -D "CMAKE_INSTALL_PREFIX=$cwd_root/archive_tmp/usr" \ -S "$prefix" -B "$prefix_build" || exit 99 cmake --build "$prefix_build" -j$(nproc) || exit 99 From 06f9a46f5ded424e75fb5d22badd00497d6f9139 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 21 Jan 2026 20:41:30 -0300 Subject: [PATCH 11/58] Jenkins: Integrate mdsx library into the build process --- .ci/build.sh | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/.ci/build.sh b/.ci/build.sh index 2262d31dcc..ced41ef406 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -12,7 +12,7 @@ # # Authors: RichardG, # -# Copyright 2021-2023 RichardG. +# Copyright 2021-2026 RichardG. # # @@ -334,6 +334,7 @@ toolchain_file="cmake/$toolchain.cmake" toolchain_file_libs= # Perform platform-specific setup. +cc_binary=gcc strip_binary=strip if is_windows then @@ -698,7 +699,7 @@ else # ...and the ones we do want listed. Non-dev packages fill missing spots on the list. libpkgs="" longest_libpkg=0 - for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev libserialport-dev libinstpatch-dev + for pkg in libc6-dev libstdc++6 libopenal-dev libfreetype6-dev libx11-dev libsdl2-dev libpng-dev librtmidi-dev qtdeclarative5-dev libwayland-dev libevdev-dev libxkbcommon-x11-dev libglib2.0-dev libslirp-dev libfaudio-dev libaudio-dev libjack-jackd2-dev libpipewire-0.3-dev libsamplerate0-dev libsndio-dev libvdeplug-dev libfluidsynth-dev libsndfile1-dev libinstpatch-dev libserialport-dev do libpkgs="$libpkgs $pkg:$arch_deb" length=$(echo -n $pkg | sed 's/-dev$//' | sed "s/qtdeclarative/qt/" | wc -c) @@ -742,6 +743,7 @@ set(ENV{PKG_CONFIG_LIBDIR} "/usr/lib/$libdir/pkgconfig:/usr/share/$libdir/pkgcon include("$(realpath "$toolchain_file")") EOF toolchain_file="$toolchain_file_new" + cc_binary="$arch_triplet-gcc" strip_binary="$arch_triplet-strip" # Create a separate toolchain file for library compilation without including @@ -881,14 +883,14 @@ then fi # Download assets if we're making a release build. +git_repo=$(git remote get-url origin 2> /dev/null) +if [ "$CI" = "true" ] +then + # Backup strategy when running under Jenkins. + [ -z "$git_repo" ] && git_repo=$GIT_URL +fi if grep -qiE "^BUILD_TYPE:[^=]+=release" build/CMakeCache.txt 2> /dev/null then - git_repo=$(git remote get-url origin 2> /dev/null) - if [ "$CI" = "true" ] - then - # Backup strategy when running under Jenkins. - [ -z "$git_repo" ] && git_repo=$GIT_URL - fi if [ -n "$git_repo" ] then echo [-] Downloading assets @@ -905,6 +907,16 @@ then fi fi +# Build mdsx library. +debug_args= +grep -qiE "^CMAKE_BUILD_TYPE:[^=]+=Debug" build/CMakeCache.txt && debug_args=DEBUG=y +cd archive_tmp +git clone --depth 1 "$(dirname "$git_repo")/mdsx.git" mdsx || exit 99 +make -C mdsx/src -j$(nproc) CC="$cc_binary" STRIP="$strip_binary" $debug_args || exit 99 +mv mdsx/src/mdsx.* . || exit 99 +rm -rf mdsx +cd .. + # Archive the executable and its dependencies. # The executable should always be archived last for the check after this block. status=0 @@ -952,6 +964,9 @@ then unzip -j "$discord_zip" "lib/$arch_discord/discord_game_sdk.dylib" -d "archive_tmp/"*".app/Contents/Frameworks" [ ! -e "archive_tmp/"*".app/Contents/Frameworks/discord_game_sdk.dylib" ] && echo [!] No Discord Game SDK for architecture [$arch_discord] + # Archive mdsx library. + mv "archive_tmp/mdsx.dylib" "archive_tmp/"*".app/Contents/Frameworks/" + # Hack to convert x86_64 binaries to x86_64h when building that architecture. if [ "$arch" = "x86_64h" ] then @@ -1137,6 +1152,9 @@ else 7z e -y -o"archive_tmp/usr/lib" "$discord_zip" "lib/$arch_discord/discord_game_sdk.so" [ ! -e "archive_tmp/usr/lib/discord_game_sdk.so" ] && echo [!] No Discord Game SDK for architecture [$arch_discord] + # Archive mdsx library. + mv "archive_tmp/mdsx.so" "archive_tmp/usr/lib/" + # Archive readme with library package versions. echo Libraries used to compile this $arch build of $project: > archive_tmp/README dpkg-query -f '${Package} ${Version}\n' -W $libpkgs | sed "s/-dev / /" | sed "s/qtdeclarative/qt/" | while IFS=" " read pkg version From e2c61d37eba80105e7ba0684e6714a4caf18f4fb Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Wed, 21 Jan 2026 21:17:39 -0300 Subject: [PATCH 12/58] Jenkins: Fix build --- .ci/dependencies_msys.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index b6c0979e27..70d00a3f73 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -15,3 +15,4 @@ qt5-translations vulkan-headers libsndfile libserialport +make From 1f0146922cd3e3586ea1233e103f842bed4b2f42 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Thu, 22 Jan 2026 00:41:08 -0300 Subject: [PATCH 13/58] Let's try again! --- .ci/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/build.sh b/.ci/build.sh index ced41ef406..e4f75457c1 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -378,7 +378,7 @@ then fi # Establish general dependencies. - pkgs="git" + pkgs="git make" # Gather installed architecture-specific packages for updating. # This prevents outdated shared libraries, unmet dependencies From bbcc7e432fb373ae1222b6b72275dab30ef9245a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Umut=20=C3=87a=C4=9Fan=20U=C3=A7anok?= Date: Wed, 21 Jan 2026 09:22:11 +0000 Subject: [PATCH 14/58] Translated using Weblate (Turkish) Currently translated at 100.0% (1004 of 1004 strings) Translation: 86Box/86Box Translate-URL: https://weblate.86box.net/projects/86box/86box/tr/ --- src/qt/languages/tr-TR.po | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index aad11ffda1..a40e07e4b4 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2026-01-01 20:06+0000\n" +"PO-Revision-Date: 2026-01-22 09:57+0000\n" "Last-Translator: Umut Çağan Uçanok \n" "Language-Team: Turkish \n" "Language: tr-TR\n" @@ -3016,10 +3016,10 @@ msgid "&Allow recompilation" msgstr "&Derlenmesine izin ver" msgid "&Fast forward" -msgstr "" +msgstr "&İleri sar" msgid "Fast forward" -msgstr "" +msgstr "İleri sar" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Sistem dizinini değiştirmek için tüm çalışan makineleri durdurun." From 57af22f32f2c6df9b8347f22ab72715b35c2fed0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jan 2026 12:31:02 +0100 Subject: [PATCH 15/58] Fix a warning in the VFIO code and attempt to use checkStateChanged instead of stateChanged when compiling with Qt 6. --- src/device/vfio.c | 2 +- src/qt/qt_mainwindow.cpp | 6 ++++-- src/qt/qt_settings.cpp | 3 ++- src/qt/qt_vmmanager_details.cpp | 6 ++++-- src/qt/qt_vmmanager_main.cpp | 6 ++++-- src/qt/qt_vmmanager_system.cpp | 4 +++- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/src/device/vfio.c b/src/device/vfio.c index b5fc077b80..2217eb509f 100644 --- a/src/device/vfio.c +++ b/src/device/vfio.c @@ -2664,7 +2664,7 @@ vfio_dev_init(vfio_device_t *dev) vfio_region_init(dev, ®, &dev->vga_mem); /* memory [A0000:BFFFF] */ /* Inform that a PCI VGA video card is attached if no video card is emulated. */ - if (gfxcard == VID_NONE) + if (gfxcard[0] == VID_NONE) video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_default); break; diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 229e9f788d..08c001ff78 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -33,6 +33,8 @@ #include "qt_cgasettingsdialog.hpp" +#include "qt_defs.hpp" + extern "C" { #include <86box/86box.h> #include <86box/config.h> @@ -936,7 +938,7 @@ MainWindow::closeEvent(QCloseEvent *event) questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_exit); - QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { + QObject::connect(chkbox, &QCheckBox::CHECK_STATE_CHANGED, [](int state) { confirm_exit = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); @@ -1221,7 +1223,7 @@ MainWindow::on_actionHard_Reset_triggered() questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_reset); - QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { + QObject::connect(chkbox, &QCheckBox::CHECK_STATE_CHANGED, [](int state) { confirm_reset = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index 3920aaeb26..312b48996f 100644 --- a/src/qt/qt_settings.cpp +++ b/src/qt/qt_settings.cpp @@ -32,6 +32,7 @@ #include "qt_progsettings.hpp" #include "qt_harddrive_common.hpp" #include "qt_settings_bus_tracking.hpp" +#include "qt_defs.hpp" extern "C" { #include <86box/86box.h> @@ -228,7 +229,7 @@ Settings::accept() QCheckBox *chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_save); - QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { confirm_save = (state == Qt::CheckState::Unchecked); }); + QObject::connect(chkbox, &QCheckBox::CHECK_STATE_CHANGED, [](int state) { confirm_save = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); if (questionbox.result() == QMessageBox::Cancel) { confirm_save = true; diff --git a/src/qt/qt_vmmanager_details.cpp b/src/qt/qt_vmmanager_details.cpp index 40d0fb1856..497f656607 100644 --- a/src/qt/qt_vmmanager_details.cpp +++ b/src/qt/qt_vmmanager_details.cpp @@ -23,6 +23,8 @@ extern "C" { #include "qt_progsettings.hpp" #include "qt_util.hpp" #include "qt_vmmanager_details.hpp" +#include "qt_defs.hpp" + #include "ui_qt_vmmanager_details.h" #define TOOLBUTTON_STYLESHEET_LIGHT "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}" @@ -279,8 +281,8 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) ui->notesTextEdit->setPlainText(passed_sysconfig->notes); ui->notesTextEdit->setEnabled(true); - disconnect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus); - connect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus); + disconnect(sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerDetails::updateProcessStatus); + connect(sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerDetails::updateProcessStatus); disconnect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus); connect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus); diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index 317bd0f2be..c0b4deab3d 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -34,6 +34,8 @@ #include "qt_vmmanager_model.hpp" #include "qt_vmmanager_addmachine.hpp" +#include "qt_defs.hpp" + extern VMManagerMainWindow *vmm_main_window; // https://stackoverflow.com/a/36460740 @@ -515,7 +517,7 @@ VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, if (!current.isValid()) return; - disconnect(selected_sysconfig->process, &QProcess::stateChanged, this, &VMManagerMain::vmStateChange); + disconnect(selected_sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerMain::vmStateChange); disconnect(selected_sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerMain::vmStateChange); disconnect(selected_sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerMain::vmStateChange); @@ -526,7 +528,7 @@ VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, // Emit that the selection changed, include with the process state emit selectionOrStateChanged(selected_sysconfig); - connect(selected_sysconfig->process, &QProcess::stateChanged, this, &VMManagerMain::vmStateChange); + connect(selected_sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerMain::vmStateChange); connect(selected_sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerMain::vmStateChange); connect(selected_sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerMain::vmStateChange); diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp index eb91ef2203..9d50589511 100644 --- a/src/qt/qt_vmmanager_system.cpp +++ b/src/qt/qt_vmmanager_system.cpp @@ -30,6 +30,8 @@ // #include "qt_vmmanager_details_section.hpp" #include "qt_vmmanager_detailsection.hpp" +#include "qt_defs.hpp" + #ifdef Q_OS_WINDOWS # include #endif @@ -101,7 +103,7 @@ VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) find86BoxBinary(); platform = QApplication::platformName(); process = new QProcess(); - connect(process, &QProcess::stateChanged, this, &VMManagerSystem::processStatusChanged); + connect(process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerSystem::processStatusChanged); // Server type for this instance (Standard should always be used instead of Legacy) socket_server_type = VMManagerServerSocket::ServerType::Standard; From 9d1b73196ce3555cfc54f0c785a3f9799122c13d Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jan 2026 12:32:23 +0100 Subject: [PATCH 16/58] The forgotten qt_defs.hpp. --- src/qt/qt_defs.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/qt/qt_defs.hpp diff --git a/src/qt/qt_defs.hpp b/src/qt/qt_defs.hpp new file mode 100644 index 0000000000..1190c0ed18 --- /dev/null +++ b/src/qt/qt_defs.hpp @@ -0,0 +1,10 @@ +#ifndef QT_DEFS_HPP +#define QT_DEFS_HPP + +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#define CHECK_STATE_CHANGED checkStateChanged +#else +#define CHECK_STATE_CHANGED stateChanged +#endif + +#endif // QT_DEFS_HPP From 3faabe6197017545f2230dbc0dad3273a4235c23 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jan 2026 12:33:43 +0100 Subject: [PATCH 17/58] It should not apply to qt_vmmanager_details.cpp. --- src/qt/qt_vmmanager_details.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/qt/qt_vmmanager_details.cpp b/src/qt/qt_vmmanager_details.cpp index 497f656607..40d0fb1856 100644 --- a/src/qt/qt_vmmanager_details.cpp +++ b/src/qt/qt_vmmanager_details.cpp @@ -23,8 +23,6 @@ extern "C" { #include "qt_progsettings.hpp" #include "qt_util.hpp" #include "qt_vmmanager_details.hpp" -#include "qt_defs.hpp" - #include "ui_qt_vmmanager_details.h" #define TOOLBUTTON_STYLESHEET_LIGHT "QToolButton {background: transparent; border: none; padding: 5px} QToolButton:hover {background: palette(midlight)} QToolButton:pressed {background: palette(mid)}" @@ -281,8 +279,8 @@ VMManagerDetails::updateData(VMManagerSystem *passed_sysconfig) ui->notesTextEdit->setPlainText(passed_sysconfig->notes); ui->notesTextEdit->setEnabled(true); - disconnect(sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerDetails::updateProcessStatus); - connect(sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerDetails::updateProcessStatus); + disconnect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus); + connect(sysconfig->process, &QProcess::stateChanged, this, &VMManagerDetails::updateProcessStatus); disconnect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus); connect(sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerDetails::updateWindowStatus); From 56bed942e7a0477f18ddae3912b3b33853c32b3f Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jan 2026 12:34:59 +0100 Subject: [PATCH 18/58] Or the other VM Manager files. --- src/qt/qt_vmmanager_main.cpp | 6 ++---- src/qt/qt_vmmanager_system.cpp | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/qt/qt_vmmanager_main.cpp b/src/qt/qt_vmmanager_main.cpp index c0b4deab3d..317bd0f2be 100644 --- a/src/qt/qt_vmmanager_main.cpp +++ b/src/qt/qt_vmmanager_main.cpp @@ -34,8 +34,6 @@ #include "qt_vmmanager_model.hpp" #include "qt_vmmanager_addmachine.hpp" -#include "qt_defs.hpp" - extern VMManagerMainWindow *vmm_main_window; // https://stackoverflow.com/a/36460740 @@ -517,7 +515,7 @@ VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, if (!current.isValid()) return; - disconnect(selected_sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerMain::vmStateChange); + disconnect(selected_sysconfig->process, &QProcess::stateChanged, this, &VMManagerMain::vmStateChange); disconnect(selected_sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerMain::vmStateChange); disconnect(selected_sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerMain::vmStateChange); @@ -528,7 +526,7 @@ VMManagerMain::currentSelectionChanged(const QModelIndex ¤t, // Emit that the selection changed, include with the process state emit selectionOrStateChanged(selected_sysconfig); - connect(selected_sysconfig->process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerMain::vmStateChange); + connect(selected_sysconfig->process, &QProcess::stateChanged, this, &VMManagerMain::vmStateChange); connect(selected_sysconfig, &VMManagerSystem::windowStatusChanged, this, &VMManagerMain::vmStateChange); connect(selected_sysconfig, &VMManagerSystem::clientProcessStatusChanged, this, &VMManagerMain::vmStateChange); diff --git a/src/qt/qt_vmmanager_system.cpp b/src/qt/qt_vmmanager_system.cpp index 9d50589511..eb91ef2203 100644 --- a/src/qt/qt_vmmanager_system.cpp +++ b/src/qt/qt_vmmanager_system.cpp @@ -30,8 +30,6 @@ // #include "qt_vmmanager_details_section.hpp" #include "qt_vmmanager_detailsection.hpp" -#include "qt_defs.hpp" - #ifdef Q_OS_WINDOWS # include #endif @@ -103,7 +101,7 @@ VMManagerSystem::VMManagerSystem(const QString &sysconfig_file) find86BoxBinary(); platform = QApplication::platformName(); process = new QProcess(); - connect(process, &QProcess::CHECK_STATE_CHANGED, this, &VMManagerSystem::processStatusChanged); + connect(process, &QProcess::stateChanged, this, &VMManagerSystem::processStatusChanged); // Server type for this instance (Standard should always be used instead of Legacy) socket_server_type = VMManagerServerSocket::ServerType::Standard; From 8c18273b23d1ac1d5169cba8fb323c5f1517bb7e Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 22 Jan 2026 19:10:00 +0100 Subject: [PATCH 19/58] Added the MSI-5156 (most of the work done by Kotochi). --- src/chipset/intel_piix.c | 6 +- src/include/86box/chipset.h | 3 + src/include/86box/machine.h | 4 ++ src/include/86box/nvr.h | 1 + src/machine/m_at_socket7.c | 125 ++++++++++++++++++++++++++++++++++++ src/machine/machine_table.c | 47 +++++++++++++- src/nvr_at.c | 85 ++++++++++++++++++------ 7 files changed, 247 insertions(+), 24 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index c6f6486d1e..9d4d88687d 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1554,7 +1554,7 @@ piix_init(const device_t *info) dev->rev = (info->local >> 4) & 0x0f; dev->func_shift = (info->local >> 8) & 0x0f; dev->no_mirq0 = (info->local >> 12) & 0x0f; - dev->func0_id = info->local >> 16; + dev->func0_id = (info->local >> 16) & 0xffff; pci_add_card(PCI_ADD_SOUTHBRIDGE, piix_read, piix_write, dev, &dev->pci_slot); piix_log("PIIX%i: Added to slot: %02X\n", dev->type, dev->pci_slot); @@ -1580,7 +1580,9 @@ piix_init(const device_t *info) dev->usb = device_add(&usb_device); if (dev->type > 3) { - if (!strcmp(machine_get_internal_name(), "ms5156")) + if (info->local & PIIX4_NVR_AMI_1995J) + dev->nvr = device_add(&piix4_ami_1995j_nvr_device); + else if (info->local & PIIX4_NVR_AMI_1995) dev->nvr = device_add(&piix4_ami_1995_nvr_device); else dev->nvr = device_add(&piix4_nvr_device); diff --git a/src/include/86box/chipset.h b/src/include/86box/chipset.h index 64b5bd88f5..4ded831bde 100644 --- a/src/include/86box/chipset.h +++ b/src/include/86box/chipset.h @@ -105,6 +105,9 @@ extern const device_t i450kx_device; extern const device_t sio_device; extern const device_t sio_zb_device; +#define PIIX4_NVR_AMI_1995 0x0000000100000000 +#define PIIX4_NVR_AMI_1995J 0x0000000200000000 + extern const device_t piix_device; extern const device_t piix_no_mirq_device; extern const device_t piix_old_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 92b448eebe..6ab3883c8a 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1097,6 +1097,10 @@ extern const device_t an430tx_device; extern int machine_at_an430tx_init(const machine_t *); extern int machine_at_ym430tx_init(const machine_t *); extern int machine_at_thunderbolt_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t ms5156_device; +#endif +extern int machine_at_ms5156_init(const machine_t *); extern int machine_at_ma23c_init(const machine_t *); extern int machine_at_mb540n_init(const machine_t *); extern int machine_at_56a5_init(const machine_t *); diff --git a/src/include/86box/nvr.h b/src/include/86box/nvr.h index 4d187b7853..9d6d789238 100644 --- a/src/include/86box/nvr.h +++ b/src/include/86box/nvr.h @@ -96,6 +96,7 @@ extern const device_t ami_1994_nvr_device; extern const device_t ami_1995_nvr_device; extern const device_t via_nvr_device; extern const device_t piix4_ami_1995_nvr_device; +extern const device_t piix4_ami_1995j_nvr_device; extern const device_t p6rp4_nvr_device; extern const device_t martin_nvr_device; extern const device_t elt_nvr_device; diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7261e2616a..24b0b9e844 100644 --- a/src/machine/m_at_socket7.c +++ b/src/machine/m_at_socket7.c @@ -1548,6 +1548,131 @@ machine_at_thunderbolt_init(const machine_t *model) return ret; } +static const device_config_t ms5156_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "ms5156w", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "AMIBIOS 6 (071595) - Revision 1.0", + .internal_name = "ms5156a", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556MS10.ROM", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 1.0 (Japanese)", + .internal_name = "ms5156aj", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556J110.ROM", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 1.0 (Traditional Chinese)", + .internal_name = "ms5156atc", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556C410.ROM", "" } + }, + { + .name = "AMIBIOS 6 (071595) - Revision 1.3 (Simplified Chinese)", + .internal_name = "ms5156asc", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/A556C313.ROM", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 1.5", + .internal_name = "ms5156w", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/W556MS15.BIN", "" } + }, + { + .name = "Award Modular BIOS v4.51PG - Revision 1.6B1 (ACPI Beta)", + .internal_name = "ms5156wab", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 131072, + .files = { "roms/machines/ms5156/W556MS16.001", "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t ms5156_device = { + .name = "MSI MS-5156", + .internal_name = "ms5156", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = ms5156_config +}; + +int +machine_at_ms5156_init(const machine_t *model) +{ + int ret; + const char *fn; + + device_context(model->device); + int is_english = !strcmp(device_get_config_bios("bios"), "ms5156a"); + int is_award = !strcmp(device_get_config_bios("bios"), "ms5156w") || !strcmp(device_get_config_bios("bios"), "ms5156wab"); + fn = device_get_bios_file(machine_get_device(machine), device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000e0000, 131072, 0); + device_context_restore(); + + 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(0x0D, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x0E, PCI_CARD_NORMAL, 2, 3, 4, 1); + pci_register_slot(0x0F, PCI_CARD_NORMAL, 3, 4, 1, 2); + pci_register_slot(0x10, PCI_CARD_NORMAL, 4, 1, 2, 3); + pci_register_slot(0x11, PCI_CARD_NORMAL, 1, 2, 3, 4); + pci_register_slot(0x07, PCI_CARD_SOUTHBRIDGE, 0, 0, 0, 4); /* PIIX4 */ + + device_add(&i430tx_device); + if (is_award) + device_add(&piix4_device); + else if (is_english) + device_add_params(&piix4_device, (void *) PIIX4_NVR_AMI_1995); + else + device_add_params(&piix4_device, (void *) PIIX4_NVR_AMI_1995J); + device_add_params(&w83977_device, (void *) (W83977TF | W83977_AMI | W83977_NO_NVR)); + device_add(&sst_flash_29ee010_device); /* assumed */ + spd_register(SPD_TYPE_SDRAM, 0x3, 128); + + return ret; +} + int machine_at_ma23c_init(const machine_t *model) { diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 2cd3db8a55..5437534ace 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -16232,6 +16232,51 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, + /* Has a Winbond W83977TF Super I/O chip with on-chip KBC with AMIKey-2 KBC + firmware. */ + { + .name = "[i430TX] MSI MS-5156", + .internal_name = "ms5156", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_ms5156_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 55000000, + .max_bus = 75000000, + .min_voltage = 2700, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_ACPI | MACHINE_USB, + .ram = { + .min = 4096, + .max = 262144, + .step = 4096 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = NULL, + .kbc_params = 0x00000000, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = &ms5156_device, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, /* Has a SM(S)C FDC37C67x Super I/O chip with on-chip KBC with Phoenix or AMI MEGAKEY '5' KBC firmware. */ { @@ -18288,7 +18333,7 @@ const machine_t machines[] = { .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB, .ram = { .min = 8192, - .max = 786432, /* Manual thinks the maximum memory is 1024MB (256x4MB), but there is no 4th memory slot */ + .max = 786432, /* Manual mistakenly says 1 GB with 256 MB in each slot, even though it only has three slots */ .step = 8192 }, .nvrmask = 255, diff --git a/src/nvr_at.c b/src/nvr_at.c index 8283c08b0e..11b5ffc457 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -289,15 +289,16 @@ #define RTC_REGS 14 /* number of registers */ -#define FLAG_NO_NMI 0x001 -#define FLAG_AMI_1992_HACK 0x002 -#define FLAG_AMI_1994_HACK 0x004 -#define FLAG_AMI_1995_HACK 0x008 -#define FLAG_AMI_1999_HACK 0x010 -#define FLAG_P6RP4_HACK 0x020 -#define FLAG_PIIX4 0x040 -#define FLAG_MULTI_BANK 0x080 -#define FLAG_MARTIN_HACK 0x100 +#define FLAG_NO_NMI 0x001 +#define FLAG_AMI_1992_HACK 0x002 +#define FLAG_AMI_1994_HACK 0x004 +#define FLAG_AMI_1995_HACK 0x008 +#define FLAG_AMI_1999_HACK 0x010 +#define FLAG_AMI_1999J_HACK 0x020 +#define FLAG_P6RP4_HACK 0x040 +#define FLAG_PIIX4 0x080 +#define FLAG_MULTI_BANK 0x100 +#define FLAG_MARTIN_HACK 0x200 typedef struct local_t { int8_t stat; @@ -578,7 +579,9 @@ nvr_reg_common_write(uint16_t reg, uint8_t val, nvr_t *nvr, local_t *local) nvr->is_new = 0; if ((reg == 0x52) && (local->flags & FLAG_AMI_1995_HACK)) nvr->is_new = 0; - if ((reg == 0x55) && (local->flags & FLAG_AMI_1999_HACK)) + if ((reg == 0x54) && (local->flags & FLAG_AMI_1999_HACK)) + nvr->is_new = 0; + if ((reg == 0x55) && (local->flags & FLAG_AMI_1999J_HACK)) nvr->is_new = 0; if ((reg >= 0x38) && (reg <= 0x3f) && local->wp[0]) return; @@ -830,6 +833,20 @@ nvr_read(uint16_t addr, void *priv) else ret = checksum & 0xff; } else if (!nvr->is_new && (local->flags & FLAG_AMI_1999_HACK)) { + /* The checksum at 3E-3F is for 37-3D and 40-73. */ + for (i = 0x37; i <= 0x3d; i++) + checksum += nvr->regs[i]; + for (i = 0x40; i <= 0x73; i++) { + if (i == 0x54) + checksum += (nvr->regs[i] & 0x3f); + else + checksum += nvr->regs[i]; + } + if (local->addr[addr_id] == 0x3e) + ret = checksum >> 8; + else + ret = checksum & 0xff; + } else if (!nvr->is_new && (local->flags & FLAG_AMI_1999J_HACK)) { /* The checksum at 3E-3F is for 37-3D and 40-73. */ for (i = 0x37; i <= 0x3d; i++) checksum += nvr->regs[i]; @@ -875,8 +892,15 @@ nvr_read(uint16_t addr, void *priv) ret = nvr->regs[local->addr[addr_id]]; break; - case 0x55: + case 0x54: if (!nvr->is_new && (local->flags & FLAG_AMI_1999_HACK)) + ret = nvr->regs[local->addr[addr_id]] & 0x3f; + else + ret = nvr->regs[local->addr[addr_id]]; + break; + + case 0x55: + if (!nvr->is_new && (local->flags & FLAG_AMI_1999J_HACK)) ret = nvr->regs[local->addr[addr_id]] & 0xfc; else ret = nvr->regs[local->addr[addr_id]]; @@ -1198,15 +1222,20 @@ nvr_at_init(const device_t *info) local->cent = RTC_CENTURY_VIA; break; case 8: /* Epson Equity LT */ - if ((info->local & 0x1f) == 0x18) { - local->flags |= (FLAG_PIIX4 | FLAG_AMI_1999_HACK); - local->def = 0x00; - nvr->irq = 8; - local->cent = RTC_CENTURY_AT; - } else { - nvr->irq = -1; - local->cent = RTC_CENTURY_ELT; - } + nvr->irq = -1; + local->cent = RTC_CENTURY_ELT; + break; + case 9: /* Intel PIIX4 + AMI 1999 hack */ + local->flags |= (FLAG_PIIX4 | FLAG_AMI_1999_HACK); + local->def = 0x00; + nvr->irq = 8; + local->cent = RTC_CENTURY_AT; + break; + case 0x0a: /* Intel PIIX4 + AMI 1999J hack */ + local->flags |= (FLAG_PIIX4 | FLAG_AMI_1999J_HACK); + local->def = 0x00; + nvr->irq = 8; + local->cent = RTC_CENTURY_AT; break; default: @@ -1485,7 +1514,21 @@ const device_t piix4_ami_1995_nvr_device = { .name = "Intel PIIX4 AMI WinBIOS 1995 PC/AT NVRAM", .internal_name = "piix4_ami_1995_nvr", .flags = DEVICE_ISA16, - .local = 0x10 | 8, + .local = 0x10 | 9, + .init = nvr_at_init, + .close = nvr_at_close, + .reset = nvr_at_reset, + .available = NULL, + .speed_changed = nvr_at_speed_changed, + .force_redraw = NULL, + .config = NULL +}; + +const device_t piix4_ami_1995j_nvr_device = { + .name = "Intel PIIX4 AMI WinBIOS 1995J PC/AT NVRAM", + .internal_name = "piix4_ami_1995j_nvr", + .flags = DEVICE_ISA16, + .local = 0x10 | 10, .init = nvr_at_init, .close = nvr_at_close, .reset = nvr_at_reset, From b09cf5aff7e8ff1e09876f561a0ab56876d64ddc Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 22 Jan 2026 20:28:07 -0300 Subject: [PATCH 20/58] Jenkins: Don't include mdsx .a if it's generated --- .ci/build.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.ci/build.sh b/.ci/build.sh index e4f75457c1..81c69a20ac 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -913,6 +913,7 @@ grep -qiE "^CMAKE_BUILD_TYPE:[^=]+=Debug" build/CMakeCache.txt && debug_args=DEB cd archive_tmp git clone --depth 1 "$(dirname "$git_repo")/mdsx.git" mdsx || exit 99 make -C mdsx/src -j$(nproc) CC="$cc_binary" STRIP="$strip_binary" $debug_args || exit 99 +rm -f mdsx/src/*.a mv mdsx/src/mdsx.* . || exit 99 rm -rf mdsx cd .. From b6adf1e5aaf7c3a88a207872733703bbc54a16b9 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 23 Jan 2026 01:05:04 +0100 Subject: [PATCH 21/58] S3 and 8514/A compatible fixes for various stuff. 1. Correct some more clock bugs of the ELSA Winner NeXTSTEP/OPENSTEP third party driver (please report any regressions if possible on other stuff). 2. Line Vector command with flag 0x211x (r/w) is now more usable (not perfect yet) and fill brushes now have correct colors (but also not perfect either) in Windows 2.x' 8514/a drivers. --- src/include/86box/vid_8514a.h | 3 + src/video/vid_8514a.c | 154 ++++++++++++++++++++++++++++------ src/video/vid_ati_mach8.c | 7 +- src/video/vid_s3.c | 126 ++++++++++++++++++---------- 4 files changed, 221 insertions(+), 69 deletions(-) diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index dddb216f68..d0cd255477 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -164,8 +164,11 @@ typedef struct ibm8514_t { int y_count; int input; int input2; + int input3; int output; int output2; + int output3; + int init_cx; int ssv_len; int ssv_len_back; diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index d521c07d5a..ca7e182b00 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -289,9 +289,9 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in val = (val >> 8) | (val << 8); } if ((cmd <= 2) || (cmd == 4) || (cmd == 6)) { - if ((dev->accel.cmd & 0x08) && (cmd >= 2)) + if ((dev->accel.cmd & 0x08) && (cmd >= 1)) { monoxfer = val; - else { + } else { if (val & 0x02) nibble |= 0x80; if (val & 0x04) @@ -893,8 +893,12 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) READ_HIGH(dev->accel.dest + dev->accel.cx, temp); } ibm8514_accel_out_pixtrans(svga, port, (temp >> 8) & 0xff, len); - } else + } else { + if (dev->accel.input3) + temp = 0xffff; + ibm8514_accel_out_pixtrans(svga, port, temp, len); + } } } break; @@ -1393,8 +1397,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 1: /*Draw line*/ if (!cpu_input) { + dev->accel.init_cx = 0; + dev->accel.input3 = 0; dev->accel.output = 0; + dev->accel.output3 = 0; dev->accel.x_count = 0; + dev->accel.xx_count = 0; dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) @@ -1406,12 +1414,20 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy = dev->accel.maj_axis_pcnt; + ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x, and3=%d, sy=%d.\n", + cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix, and3, dev->accel.sy); + ibm8514_log("Line Draw 8514/A CMD=%04x, frgdmix=%d, bkgdmix=%d, c(%d,%d), pixcntl=%d, sy=%d, polyfill=%x, selfrmix=%02x, selbkmix=%02x, bkgdcol=%02x, frgdcol=%02x, clipt=%d, clipb=%d.\n", dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.multifunc[0x0a] & 6, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, bkgd_color, frgd_color, dev->accel.clip_top, clip_b); if (ibm8514_cpu_src(svga)) { if (dev->accel.cmd & 0x02) { if (!(dev->accel.cmd & 0x1000)) { - if (dev->accel.cmd & 0x08) - dev->accel.output = 1; + if (dev->accel.cmd & 0x08) { + if (dev->accel.cmd == 0x211b) { + dev->accel.x_count = dev->accel.cx - (and3 + 3); + dev->accel.sy += (and3 + 3); + } else + dev->accel.output = 1; + } } } dev->force_busy = 1; @@ -1420,11 +1436,20 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->data_available2 = 0; return; /*Wait for data from CPU*/ } else if (ibm8514_cpu_dest(svga)) { + if (dev->accel.cmd & 0x02) { + if (!(dev->accel.cmd & 0x1000)) { + if (dev->accel.cmd & 0x08) { + if ((frgd_mix == 3) && (bkgd_mix == 3) && (pixcntl == 0) && + ((dev->accel.multifunc[0x0a] & 0x06) == 0x04) && (dev->accel.frgd_mix != 0x07)) /*Kinda of a workaround for fill brushes on 8514/A using Windows 2.x*/ + dev->accel.input3 = 1; + } + } + } dev->force_busy = 1; dev->force_busy2 = 1; dev->data_available = 1; dev->data_available2 = 1; - return; + return; /*Wait for data from CPU*/ } } @@ -1432,10 +1457,17 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (ibm8514_cpu_dest(svga) && cpu_input && (dev->accel.cmd & 0x02)) count >>= 1; - if (dev->accel.cmd & 0x02) - ibm8514_log("Line Draw Vector Single pixtrans=%04x, count=%d.\n", mix_dat, count); + if (dev->accel.cmd == 0x211b) { + if (and3 >= 2) { + if (dev->accel.sy < (count << 1)) + count <<= 1; + } + } + if (dev->accel.cmd & 0x1000) + ibm8514_log("Vector Line %d: full=%04x, odd=%d, c(%d,%d), frgdmix=%d, bkgdmix=%d, xcount=%d, and3=%d, len(%d,%d), CURX=%d, Width=%d, pixcntl=%d, mix_dat=%08x, count=%d, cpu_data=%08x, cpu_input=%d.\n", cmd, dev->accel.cmd, dev->accel.input, dev->accel.cx, dev->accel.cy, frgd_mix, bkgd_mix, dev->accel.x_count, and3, dev->accel.sx, dev->accel.sy, dev->accel.cur_x, dev->accel.maj_axis_pcnt, pixcntl, mix_dat, count, cpu_dat, cpu_input); while (count-- && (dev->accel.sy >= 0)) { + ibm8514_log("CurrentX=%d, CurrentY=%d, Count=%d.\n", dev->accel.cx, dev->accel.cy, count); if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && (dev->accel.cy >= clip_t) && @@ -1455,6 +1487,17 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (pixcntl == 3) src_dat = ((src_dat & rd_mask) == rd_mask); } else { + if (dev->accel.cmd == 0x211b) { + if (dev->accel.x_count != dev->accel.cx) { + dev->accel.output3 = 1; + } else { + dev->accel.output3 = 0; + } + + if (dev->accel.output3 == 1) + goto skip_vector_line_write; + } + if (dev->accel.output) { switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { case 0: @@ -1523,6 +1566,12 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } else if (!(dev->accel.cmd & 0x04)) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); } + } else if (dev->accel.input3) { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat ? dest_dat : 0xff); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat ? dest_dat : 0xff); + } } } } @@ -1542,13 +1591,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat break; } - if (dev->accel.output) - mix_dat >>= 1; - else { - mix_dat <<= 1; - mix_dat |= 1; - } - if (dev->bpp) cpu_dat >>= 16; else @@ -1560,37 +1602,90 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat break; case 0x20: dev->accel.cx++; - dev->accel.cy--; + if (!dev->accel.output3) + dev->accel.cy--; break; case 0x40: - dev->accel.cy--; + if (!dev->accel.output3) + dev->accel.cy--; break; case 0x60: dev->accel.cx--; - dev->accel.cy--; + if (!dev->accel.output3) + dev->accel.cy--; break; case 0x80: dev->accel.cx--; break; case 0xa0: dev->accel.cx--; - dev->accel.cy++; + if (!dev->accel.output3) + dev->accel.cy++; break; case 0xc0: - dev->accel.cy++; + if (!dev->accel.output3) + dev->accel.cy++; break; case 0xe0: dev->accel.cx++; - dev->accel.cy++; + if (!dev->accel.output3) + dev->accel.cy++; + break; + + default: + break; + } + +skip_vector_line_write: + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.x_count++; + break; + case 0x20: + dev->accel.x_count++; + if (dev->accel.output3) + dev->accel.cy--; + break; + case 0x40: + if (dev->accel.output3) + dev->accel.cy--; + break; + case 0x60: + dev->accel.x_count--; + if (dev->accel.output3) + dev->accel.cy--; + break; + case 0x80: + dev->accel.x_count--; + break; + case 0xa0: + dev->accel.x_count--; + if (dev->accel.output3) + dev->accel.cy++; + break; + case 0xc0: + if (dev->accel.output3) + dev->accel.cy++; + break; + case 0xe0: + dev->accel.x_count++; + if (dev->accel.output3) + dev->accel.cy++; break; default: break; } + if (dev->accel.output) + mix_dat >>= 1; + else { + mix_dat <<= 1; + mix_dat |= 1; + } + dev->accel.sy--; } - dev->accel.x_count = 0; dev->accel.output = 0; } else { /*Bresenham Line*/ if (pixcntl == 1) { @@ -1819,6 +1914,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.output = 0; dev->accel.input = 0; dev->accel.input2 = 0; + dev->accel.input3 = 0; dev->accel.odd_in = 0; dev->accel.cx = dev->accel.cur_x; @@ -1832,6 +1928,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; + ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x.\n", + cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix); + dev->accel.dest = dev->accel.ge_offset + (dev->accel.cy * dev->pitch); if (cmd == 4) @@ -1883,9 +1982,13 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sx -= 2; } } + } else { + if ((dev->accel.cmd == 0x41f0) && (frgd_mix == 3) && (bkgd_mix == 3) && + (pixcntl == 0)) + dev->accel.input3 = 1; } } - ibm8514_log("INPUT=%d.\n", dev->accel.input); + ibm8514_log("INPUT1=%d, INPUT2=%d.\n", dev->accel.input, dev->accel.input2); dev->force_busy = 1; dev->force_busy2 = 1; dev->data_available = 1; @@ -2056,7 +2159,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat ibm8514_log("Vectored Rectangle with normal processing (TODO).\n"); } else { /*Normal Rectangle*/ if (cpu_input) { - ibm8514_log("Normal Pixel Rectangle Fill Transfer SY=%d.\n", dev->accel.sy); + ibm8514_log("Normal Pixel Rectangle Fill Transfer SY=%d, fullcmd=%04x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, polygontype=%02x, pixcntl=%x, curx=%d, cury=%d.\n", dev->accel.sy, dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.multifunc[0x0a] & 0x06, pixcntl, dev->accel.cx, dev->accel.cy); while (count-- && (dev->accel.sy >= 0)) { if ((dev->accel.cx >= clip_l) && (dev->accel.cx <= clip_r) && @@ -2844,6 +2947,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; + ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, destx=%d, desty=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x.\n", + cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, dev->accel.dx, dev->accel.dy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix); + dev->accel.src = dev->accel.ge_offset + (dev->accel.cy * dev->pitch); dev->accel.dest = dev->accel.ge_offset + (dev->accel.dy * dev->pitch); dev->accel.fill_state = 0; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 81abadd566..ccb1941460 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -915,7 +915,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (dev->accel.cx > 0) dev->accel.cx--; mach_log("BitBLT: Src Negative X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", - mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config + mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); } else { mach->accel.src_stepx = 1; @@ -4717,6 +4717,11 @@ mach_accel_in_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, in dev->force_busy = 1; dev->data_available = 1; } + if (dev->accel.input3) + temp = 0xffff; + + mach_log("Opcode=%d, Len=%d, port=%04x, input=%d, temp=%04x, fullcmd=%04x, crx=%d, cry=%d, frgdsel=%x, bkgdsel=%x.\n", cmd, len, port, dev->accel.input, temp, dev->accel.cmd, dev->accel.cx, dev->accel.cy, dev->accel.frgd_sel, dev->accel.bkgd_sel); + if (dev->accel.input) { ibm8514_accel_out_pixtrans(svga, port, temp & 0xff, len); if (dev->accel.odd_in) { /*WORDs on odd destination scan lengths.*/ diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 101d3ae8bf..fc7499ff66 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -1924,7 +1924,9 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) static void s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) { - if ((port != 0x9ee8) && (port != 0x9d48)) { + int port_pixtrans = ((port != 0x9ae8) && (port != 0x9948) && (port != 0x9ee8) && (port != 0x9d48)); + + if (port_pixtrans) { s3_log("[%04X:%08X] OUT PORTW=%04x, val=%04x, CMD=%04x, C(%d,%d), WRTMASK=%04x.\n", CS, cpu_state.pc, port, val, s3->accel.cmd, s3->accel.cur_x, s3->accel.cur_y, s3->accel.wrt_mask); s3_log(".\n"); if ((port == 0xb2e8) || (port == 0xb148)) { @@ -1946,18 +1948,30 @@ s3_accel_out_fifo_w(s3_t *s3, uint16_t port, uint16_t val) } } } else { - s3->accel.short_stroke = val; - s3->accel.ssv_state = 1; + switch (port) { + case 0x9948: + case 0x9ae8: + s3_accel_out_fifo(s3, port, val); + s3_accel_out_fifo(s3, port + 1, val >> 8); + break; + case 0x9d48: + case 0x9ee8: + s3->accel.short_stroke = val; + s3->accel.ssv_state = 1; - s3->accel.cx = s3->accel.cur_x & 0xfff; - s3->accel.cy = s3->accel.cur_y & 0xfff; + s3->accel.cx = s3->accel.cur_x & 0xfff; + s3->accel.cy = s3->accel.cur_y & 0xfff; - if (s3->accel.cmd & 0x1000) { - s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); - s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); - } else { - s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); - s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); + if (s3->accel.cmd & 0x1000) { + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); + } else { + s3_short_stroke_start(s3, s3->accel.short_stroke >> 8); + s3_short_stroke_start(s3, s3->accel.short_stroke & 0xff); + } + break; + default: + break; } } } @@ -2857,7 +2871,7 @@ s3_io_remove_alt(s3_t *s3) io_removehandler(0x8d48, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x9148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x9548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9948, 0x0004, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2883,6 +2897,7 @@ s3_io_remove(s3_t *s3) io_removehandler(0x03c0, 0x0020, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); io_removehandler(0x82ec, 0x0002, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + io_removehandler(0x02e8, 0x0002, s3_in, NULL, NULL, NULL, NULL, NULL, s3); io_removehandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2892,7 +2907,7 @@ s3_io_remove(s3_t *s3) io_removehandler(0x8ee8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x92e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0x96e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); - io_removehandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_removehandler(0x9ae8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_removehandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_removehandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2946,9 +2961,10 @@ s3_io_set_alt(s3_t *s3) io_sethandler(0x9548, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); } if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - io_sethandler(0x9948, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9948, 0x0004, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); else - io_sethandler(0x9948, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9948, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_sethandler(0x9d48, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_sethandler(0xa148, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xa548, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -2984,6 +3000,8 @@ s3_io_set(s3_t *s3) } io_sethandler(0x82ec, 0x0002, s3_in, NULL, NULL, s3_out, NULL, NULL, s3); + + io_sethandler(0x02e8, 0x0002, s3_in, NULL, NULL, NULL, NULL, NULL, s3); io_sethandler(0x42e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x46e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0x4ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -3003,9 +3021,10 @@ s3_io_set(s3_t *s3) io_sethandler(0x96e8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); } if (s3->chip == S3_VISION968 || s3->chip == S3_VISION868) - io_sethandler(0x9ae8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9ae8, 0x0004, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); else - io_sethandler(0x9ae8, 0x0002, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); + io_sethandler(0x9ae8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); + io_sethandler(0x9ee8, 0x0002, s3_accel_in, s3_accel_in_w, NULL, s3_accel_out, s3_accel_out_w, NULL, s3); io_sethandler(0xa2e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); io_sethandler(0xa6e8, 0x0004, s3_accel_in, NULL, NULL, s3_accel_out, NULL, NULL, s3); @@ -3085,6 +3104,7 @@ s3_out(uint16_t addr, uint8_t val, void *priv) else svga->write_bank = svga->read_bank = s3->bank << 14; + s3_log("Chain4=%02x.\n", svga->chain4); svga_recalctimings(svga); } else if (svga->seqaddr == 9) { svga->seqregs[9] = val & 0x80; @@ -3432,6 +3452,14 @@ s3_in(uint16_t addr, void *priv) s3_log("%04X:%08X: %03X: s3_in.\n", CS, cpu_state.pc, addr); switch (addr) { + case 0x2e8: + temp = 0; + if (svga->vc == svga->vsyncstart) { + if (s3->accel.advfunc_cntl & 0x04) + temp |= 0x02; + } + return temp; + case 0x3c1: if (svga->attraddr > 0x14) return 0xff; @@ -4114,8 +4142,10 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock >>= 1; svga->clock *= 2.0; } else { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; + if (clk_sel != 2) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } } } break; @@ -4197,6 +4227,9 @@ s3_recalctimings(svga_t *svga) if (!s3->elsa_eeprom) { if (svga->hdisp == 832) svga->hdisp -= 32; + } else { + if (clk_sel > 7) + svga->clock *= 2.0; } break; case TVP3026: /*TVP3026 RAMDAC and clock chip*/ @@ -4316,8 +4349,10 @@ s3_recalctimings(svga_t *svga) svga->dots_per_clock >>= 1; svga->clock *= 2.0; } else { - svga->hdisp >>= 1; - svga->dots_per_clock >>= 1; + if (clk_sel != 2) { + svga->hdisp >>= 1; + svga->dots_per_clock >>= 1; + } } } break; @@ -4655,6 +4690,9 @@ s3_recalctimings(svga_t *svga) if (!s3->elsa_eeprom) { if (svga->hdisp == 832) svga->hdisp -= 32; + } else { + if (clk_sel > 7) + svga->clock *= 2.0; } break; case TVP3026: /*TVP3026 RAMDAC and clock chip*/ @@ -4989,7 +5027,7 @@ s3_updatemapping(s3_t *s3) /*Linear framebuffer*/ mem_mapping_disable(&svga->mapping); - switch (svga->crtc[0x58] & 3) { + switch (svga->crtc[0x58] & 0x03) { case 0: /*64k*/ s3->linear_size = 0x10000; break; @@ -4999,7 +5037,7 @@ s3_updatemapping(s3_t *s3) case 2: /*2mb*/ s3->linear_size = 0x200000; break; - case 3: /*8mb*/ + case 3: /*8mb*/ switch (s3->chip) { /* Not on video cards that don't support 4MB*/ case S3_TRIO64: case S3_TRIO64V: @@ -5098,7 +5136,7 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; - s3_log("%04X:%08X: OUTB FIFO=%04x, val=%02x.\n", CS, cpu_state.pc, port, val); + s3_log("%04X:%08X: OUTB FIFO=%04x, val=%02x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, val, s3->enable_8514); if (port >= 0x8000) { if (!s3->enable_8514) @@ -5121,9 +5159,11 @@ s3_accel_out(uint16_t port, uint8_t val, void *priv) s3->accel.subsys_cntl = (s3->accel.subsys_cntl & 0xff) | (val << 8); s3_update_irqs(s3); break; + case 0x45e8: case 0x46e8: s3->accel.setup_md = (s3->accel.setup_md & 0xff00) | val; break; + case 0x45e9: case 0x46e9: s3->accel.setup_md = (s3->accel.setup_md & 0xff) | (val << 8); break; @@ -5151,7 +5191,7 @@ s3_accel_out_w(uint16_t port, uint16_t val, void *priv) { s3_t *s3 = (s3_t *) priv; - s3_log("%04X:%08X: OUTW FIFO=%04x, val=%04x.\n", CS, cpu_state.pc, port, val); + s3_log("%04X:%08X: OUTW FIFO=%04x, val=%04x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, val, s3->enable_8514); if (!s3->enable_8514) return; @@ -5185,8 +5225,9 @@ s3_accel_in(uint16_t port, void *priv) svga_t *svga = &s3->svga; int temp; uint8_t temp2 = 0x00; + int enhanced_8bpp_modes = !!((svga->crtc[0x3a] & 0x10) && !svga->lowres); - s3_log("%04X:%08X: INB=%04x.\n", CS, cpu_state.pc, port); + s3_log("%04X:%08X: INB=%04x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, s3->enable_8514); if (!s3->enable_8514) return 0xff; @@ -5194,7 +5235,7 @@ s3_accel_in(uint16_t port, void *priv) switch (port) { case 0x4148: case 0x42e8: - return s3->subsys_stat; + return s3->subsys_stat | (enhanced_8bpp_modes ? 0x80 : 0x00); case 0x4149: case 0x42e9: return s3->accel.subsys_cntl >> 8; @@ -5331,20 +5372,10 @@ s3_accel_in(uint16_t port, void *priv) if (s3->force_busy) temp |= 0x02; /*Hardware busy*/ else { - switch (s3->accel.cmd >> 13) { /*Some drivers may not set FIFO on but may still turn on FIFO empty bits!*/ + switch (s3->accel.cmd >> 13) { /*Some drivers may not set FIFO on but may still turn FIFO empty bits on!*/ case 0: - if (s3->accel.cmd & 0x100) { - if (!s3->accel.ssv_len) - temp |= 0x04; - } else - temp |= 0x04; - break; case 1: - if (s3->accel.cmd & 0x100) { - if (!s3->accel.sy) - temp |= 0x04; - } else - temp |= 0x04; + temp |= 0x04; break; case 2: case 6: @@ -6305,11 +6336,14 @@ s3_accel_in_w(uint16_t port, void *priv) uint16_t temp1 = 0x0000; uint16_t temp2 = 0x0000; const uint16_t *vram_w = (uint16_t *) svga->vram; + int port_pixtrans = ((port != 0x9ae8) && (port != 0x9948) && (port != 0x9ee8) && (port != 0x9d48)); + + s3_log("%04X:%08X: INW=%04x, 8514/A functions=%x.\n", CS, cpu_state.pc, port, s3->enable_8514); if (!s3->enable_8514) return 0xffff; - if (port != 0x9ee8 && port != 0x9d48) { + if (port_pixtrans) { if (s3_cpu_dest(s3)) { READ_PIXTRANS_WORD @@ -6377,10 +6411,8 @@ s3_accel_in_w(uint16_t port, void *priv) } } } else { - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - - temp = s3->accel.short_stroke; + temp = s3_accel_in(port, s3); + temp |= (s3_accel_in(port + 1, s3) << 8); } return temp; @@ -6451,6 +6483,8 @@ s3_accel_write(uint32_t addr, uint8_t val, void *priv) const svga_t *svga = &s3->svga; uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff; + s3_log("%04X:%08X: WRITEB, 8514/A functions=%x.\n", CS, cpu_state.pc, s3->enable_8514); + if (!s3->enable_8514) return; @@ -6494,6 +6528,8 @@ s3_accel_write_w(uint32_t addr, uint16_t val, void *priv) const svga_t *svga = &s3->svga; uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff; + s3_log("%04X:%08X: WRITEW, 8514/A functions=%x.\n", CS, cpu_state.pc, s3->enable_8514); + if (!s3->enable_8514) return; @@ -6528,6 +6564,8 @@ s3_accel_write_l(uint32_t addr, uint32_t val, void *priv) svga_t *svga = &s3->svga; uint32_t addr_mask = (svga->crtc[0x53] & 0x08) ? 0x1ffff : 0xffff; + s3_log("%04X:%08X: WRITEL, 8514/A functions=%x.\n", CS, cpu_state.pc, s3->enable_8514); + if (!s3->enable_8514) return; From 233900c15eb635aa4d404b4d4b7a58aca30fadc9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Jan 2026 01:41:49 +0100 Subject: [PATCH 22/58] DEC Tulip: Reject transmissions with NO CARRIER error when link it down, fixes #6743. --- src/network/net_tulip.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 298cda2329..3f1825a1e1 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -733,7 +733,9 @@ tulip_tx(TULIPState *s, struct tulip_descriptor *desc) if ((s->csr[6] >> CSR6_OM_SHIFT) & CSR6_OM_MASK) { /* Internal or external Loopback */ tulip_receive(s, s->tx_frame, s->tx_frame_len); - } else if (s->tx_frame_len <= sizeof(s->tx_frame)) { + } else if (net_cards_conf[s->nic->card_num].link_state & NET_LINK_DOWN) + desc->status |= (TDES0_ES | TDES0_NC); + else if (s->tx_frame_len <= sizeof(s->tx_frame)) { //pclog("Transmit!.\n"); network_tx(s->nic, s->tx_frame, s->tx_frame_len); } From 7ecfc5422f06fab4d519b31a9d046951ab969737 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Jan 2026 02:46:01 +0100 Subject: [PATCH 23/58] Network: Send all packets to the void and receive nothing if the cable is disconnected. --- src/network/net_pcap.c | 21 +++++++++++++-------- src/network/net_slirp.c | 31 ++++++++++++++++++++----------- src/network/net_switch.c | 30 +++++++++++++++++------------- src/network/net_vde.c | 13 ++++++++----- 4 files changed, 58 insertions(+), 37 deletions(-) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index e0c6804f41..abfd9dea86 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -235,7 +235,8 @@ net_pcap_rx_handler(uint8_t *user, const struct pcap_pkthdr *h, const uint8_t *b net_pcap_t *pcap = (net_pcap_t *) user; memcpy(pcap->pkt.data, bytes, h->caplen); pcap->pkt.len = h->caplen; - network_rx_put_pkt(pcap->card, &pcap->pkt); + if (!(net_cards_conf[pcap->card->card_num].link_state & NET_LINK_DOWN)) + network_rx_put_pkt(pcap->card, &pcap->pkt); } /* Send a packet to the Pcap interface. */ @@ -282,12 +283,14 @@ net_pcap_thread(void *priv) case NET_EVENT_TX: net_event_clear(&pcap->tx_event); - int packets = network_tx_popv(pcap->card, pcap->pktv, PCAP_PKT_BATCH); - for (int i = 0; i < packets; i++) { - h.caplen = pcap->pktv[i].len; - f_pcap_sendqueue_queue(pcap->pcap_queue, &h, pcap->pktv[i].data); + if (!(net_cards_conf[pcap->card->card_num].link_state & NET_LINK_DOWN)) { + int packets = network_tx_popv(pcap->card, pcap->pktv, PCAP_PKT_BATCH); + for (int i = 0; i < packets; i++) { + h.caplen = pcap->pktv[i].len; + f_pcap_sendqueue_queue(pcap->pcap_queue, &h, pcap->pktv[i].data); + } + f_pcap_sendqueue_transmit(pcap->pcap, pcap->pcap_queue, 0); } - f_pcap_sendqueue_transmit(pcap->pcap, pcap->pcap_queue, 0); pcap->pcap_queue->len = 0; break; @@ -333,8 +336,10 @@ net_pcap_thread(void *priv) net_event_clear(&pcap->tx_event); int packets = network_tx_popv(pcap->card, pcap->pktv, PCAP_PKT_BATCH); - for (int i = 0; i < packets; i++) { - net_pcap_in(pcap->pcap, pcap->pktv[i].data, pcap->pktv[i].len); + if (!(net_cards_conf[pcap->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) { + net_pcap_in(pcap->pcap, pcap->pktv[i].data, pcap->pktv[i].len); + } } } diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index 4f61a55a88..c7243baacb 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -193,11 +193,14 @@ net_slirp_send_packet(const void *qp, size_t pkt_len, void *opaque) memcpy(slirp->pkt.data, (uint8_t *) qp, pkt_len); slirp->pkt.len = pkt_len; - if (slirp->during_tx) { - network_rx_on_tx_put_pkt(slirp->card, &slirp->pkt); - slirp->recv_on_tx = 1; - } else - network_rx_put_pkt(slirp->card, &slirp->pkt); + + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + if (slirp->during_tx) { + network_rx_on_tx_put_pkt(slirp->card, &slirp->pkt); + slirp->recv_on_tx = 1; + } else + network_rx_put_pkt(slirp->card, &slirp->pkt); + } return pkt_len; } @@ -362,8 +365,10 @@ net_slirp_rx_deferred_packets(net_slirp_t *slirp) if (slirp->recv_on_tx) { do { packets = network_rx_on_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH); - for (int i = 0; i < packets; i++) - network_rx_put_pkt(slirp->card, &(slirp->pkt_tx_v[i])); + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + network_rx_put_pkt(slirp->card, &(slirp->pkt_tx_v[i])); + } } while (packets > 0); slirp->recv_on_tx = 0; } @@ -403,8 +408,10 @@ net_slirp_thread(void *priv) { slirp->during_tx = 1; int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH); - for (int i = 0; i < packets; i++) - net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + } slirp->during_tx = 0; net_slirp_rx_deferred_packets(slirp); @@ -456,8 +463,10 @@ net_slirp_thread(void *priv) slirp->during_tx = 1; int packets = network_tx_popv(slirp->card, slirp->pkt_tx_v, SLIRP_PKT_BATCH); - for (int i = 0; i < packets; i++) - net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + if (!(net_cards_conf[slirp->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + net_slirp_in(slirp, slirp->pkt_tx_v[i].data, slirp->pkt_tx_v[i].len); + } slirp->during_tx = 0; net_slirp_rx_deferred_packets(slirp); diff --git a/src/network/net_switch.c b/src/network/net_switch.c index 5fc3a20917..d29513f746 100644 --- a/src/network/net_switch.c +++ b/src/network/net_switch.c @@ -372,25 +372,29 @@ net_switch_thread(void *priv) net_event_clear(&netswitch->tx_event); netswitch->during_tx = 1; packets = network_tx_popv(netswitch->card, netswitch->pkt_tx_v, SWITCH_PKT_BATCH); - for (int i = 0; i < packets; i++) { + if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) { #define MAC_FORMAT "(%02X:%02X:%02X:%02X:%02X:%02X -> %02X:%02X:%02X:%02X:%02X:%02X)" #define MAC_FORMAT_ARGS(p) (p)[6], (p)[7], (p)[8], (p)[9], (p)[10], (p)[11], (p)[0], (p)[1], (p)[2], (p)[3], (p)[4], (p)[5] - netswitch_log("Network Switch: sending %d-byte packet " MAC_FORMAT "\n", - netswitch->pkt_tx_v[i].len, MAC_FORMAT_ARGS(netswitch->pkt_tx_v[i].data)); - - /* Send through all known host interfaces. */ - for (net_switch_hostaddr_t *hostaddr = netswitch->hostaddrs; hostaddr; hostaddr = hostaddr->next) - sendto(hostaddr->socket_tx, - (char *) netswitch->pkt_tx_v[i].data, netswitch->pkt_tx_v[i].len, 0, - &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); + netswitch_log("Network Switch: sending %d-byte packet " MAC_FORMAT "\n", + netswitch->pkt_tx_v[i].len, MAC_FORMAT_ARGS(netswitch->pkt_tx_v[i].data)); + + /* Send through all known host interfaces. */ + for (net_switch_hostaddr_t *hostaddr = netswitch->hostaddrs; hostaddr; hostaddr = hostaddr->next) + sendto(hostaddr->socket_tx, + (char *) netswitch->pkt_tx_v[i].data, netswitch->pkt_tx_v[i].len, 0, + &hostaddr->addr_tx.sa, sizeof(hostaddr->addr_tx.sa)); + } } netswitch->during_tx = 0; if (netswitch->recv_on_tx) { do { packets = network_rx_on_tx_popv(netswitch->card, netswitch->pkt_tx_v, SWITCH_PKT_BATCH); - for (int i = 0; i < packets; i++) - network_rx_put_pkt(netswitch->card, &(netswitch->pkt_tx_v[i])); + if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i = 0; i < packets; i++) + network_rx_put_pkt(netswitch->card, &(netswitch->pkt_tx_v[i])); + } } while (packets > 0); netswitch->recv_on_tx = 0; } @@ -407,9 +411,9 @@ net_switch_thread(void *priv) netswitch_log("Network Switch: recv error (%d)\n", len); } else if ((AS_U64(netswitch->pkt.data[6]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64) { /* A packet we've sent has looped back, drop it. */ - } else if (netswitch->promisc || /* promiscuous mode? */ + } else if (!(net_cards_conf[netswitch->card->card_num].link_state & NET_LINK_DOWN) && (netswitch->promisc || /* promiscuous mode? */ (netswitch->pkt.data[0] & 1) || /* broadcast packet? */ - ((AS_U64(netswitch->pkt.data[0]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64)) { /* packet for me? */ + ((AS_U64(netswitch->pkt.data[0]) & le64_to_cpu(0xffffffffffffULL)) == netswitch->mac_addr_u64))) { /* packet for me? */ netswitch_log("Network Switch: receiving %d-byte packet " MAC_FORMAT "\n", len, MAC_FORMAT_ARGS(netswitch->pkt.data)); netswitch->pkt.len = len; diff --git a/src/network/net_vde.c b/src/network/net_vde.c index 4f8d5c21f7..6e82d46695 100644 --- a/src/network/net_vde.c +++ b/src/network/net_vde.c @@ -151,10 +151,12 @@ static void net_vde_thread(void *priv) { if (pfd[NET_EVENT_TX].revents & POLLIN) { net_event_clear(&vde->tx_event); int packets = network_tx_popv(vde->card, vde->pktv, VDE_PKT_BATCH); - for (int i=0; ivdeconn, vde->pktv[i].data,vde->pktv[i].len, 0 ); - if (nc == 0) { - vde_log("VDE: Problem, no bytes sent.\n"); + if (!(net_cards_conf[vde->card->card_num].link_state & NET_LINK_DOWN)) { + for (int i=0; ivdeconn, vde->pktv[i].data,vde->pktv[i].len, 0 ); + if (nc == 0) { + vde_log("VDE: Problem, no bytes sent.\n"); + } } } } @@ -163,7 +165,8 @@ static void net_vde_thread(void *priv) { if (pfd[NET_EVENT_RX].revents & POLLIN) { int nc = f_vde_recv(vde->vdeconn, vde->pkt.data, NET_MAX_FRAME, 0); vde->pkt.len = nc; - network_rx_put_pkt(vde->card, &vde->pkt); + if (!(net_cards_conf[vde->card->card_num].link_state & NET_LINK_DOWN)) + network_rx_put_pkt(vde->card, &vde->pkt); } // We have been told to close From f275ead19487baad110bdd909c608abf285c738c Mon Sep 17 00:00:00 2001 From: Maxwell Scott Date: Fri, 23 Jan 2026 08:49:38 +0700 Subject: [PATCH 24/58] Rename ASUS TX97-HP to its HP OEM name --- src/machine/machine_table.c | 90 ++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5437534ace..e113f3fe04 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -15904,51 +15904,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, - /* Has a National Semiconductor PC87307 Super I/O with on-chip KBC, which has one of these - firmwares: AMI '5' MegaKey, Phoenix MultiKey/42 1.37, or Phoenix MultiKey/42i 4.16. */ - { - .name = "[i430TX] ASUS TX97-XV (HP OEM)", - .internal_name = "tx97xv", - .type = MACHINE_TYPE_SOCKET7, - .chipset = MACHINE_CHIPSET_INTEL_430TX, - .init = machine_at_tx97xv_init, - .p1_handler = machine_generic_p1_handler, - .gpio_handler = NULL, - .available_flag = MACHINE_AVAILABLE, - .gpio_acpi_handler = NULL, - .cpu = { - .package = CPU_PKG_SOCKET5_7, - .block = CPU_BLOCK_NONE, - .min_bus = 50000000, - .max_bus = 75000000, - .min_voltage = 2100, - .max_voltage = 3520, - .min_multi = 1.5, - .max_multi = 3.5 - }, - .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, - .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB | MACHINE_VIDEO, - .ram = { - .min = 8192, - .max = 262144, - .step = 8192 - }, - .nvrmask = 255, - .jumpered_ecp_dma = 0, - .default_jumpered_ecp_dma = -1, - .kbc_device = &kbc_at_device, - .kbc_params = KBC_VEN_AMI | 0x00004600, - .kbc_p1 = 0x00000cf0, - .gpio = 0xffffffff, - .gpio_acpi = 0xffffffff, - .device = NULL, - .kbd_device = NULL, - .fdc_device = NULL, - .sio_device = NULL, - .vid_device = &mach64vt3_onboard_device, - .snd_device = NULL, - .net_device = NULL - }, /* This has the AMIKey KBC firmware, which is type 'F' (YM430TX is based on the TX97). */ { .name = "[i430TX] ASUS TX97", @@ -16091,6 +16046,51 @@ const machine_t machines[] = { .snd_device = &cs4236b_onboard_device, .net_device = &pcnet_am79c973_onboard_device }, + /* Has a National Semiconductor PC87307 Super I/O with on-chip KBC, which has one of these + firmwares: AMI '5' MegaKey, Phoenix MultiKey/42 1.37, or Phoenix MultiKey/42i 4.16. */ + { + .name = "[i430TX] HP Pavilion 81xx (ASUS TX97-XV)", + .internal_name = "tx97xv", + .type = MACHINE_TYPE_SOCKET7, + .chipset = MACHINE_CHIPSET_INTEL_430TX, + .init = machine_at_tx97xv_init, + .p1_handler = machine_generic_p1_handler, + .gpio_handler = NULL, + .available_flag = MACHINE_AVAILABLE, + .gpio_acpi_handler = NULL, + .cpu = { + .package = CPU_PKG_SOCKET5_7, + .block = CPU_BLOCK_NONE, + .min_bus = 50000000, + .max_bus = 75000000, + .min_voltage = 2100, + .max_voltage = 3520, + .min_multi = 1.5, + .max_multi = 3.5 + }, + .bus_flags = MACHINE_PS2_PCI | MACHINE_BUS_USB, + .flags = MACHINE_IDE_DUAL | MACHINE_APM | MACHINE_USB | MACHINE_VIDEO, + .ram = { + .min = 8192, + .max = 262144, + .step = 8192 + }, + .nvrmask = 255, + .jumpered_ecp_dma = 0, + .default_jumpered_ecp_dma = -1, + .kbc_device = &kbc_at_device, + .kbc_params = KBC_VEN_AMI | 0x00004600, + .kbc_p1 = 0x00000cf0, + .gpio = 0xffffffff, + .gpio_acpi = 0xffffffff, + .device = NULL, + .kbd_device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = &mach64vt3_onboard_device, + .snd_device = NULL, + .net_device = NULL + }, /* This has the Phoenix MultiKey KBC firmware on the NSC Super I/O chip. */ { .name = "[i430TX] Intel AN430TX (Anchorage)", From 72a4cc25b5ebb337e0b9c34f291f6a03e3a1e135 Mon Sep 17 00:00:00 2001 From: kotochi98 <185547947+kotochi98@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:13:35 +0300 Subject: [PATCH 25/58] Remove the Elonex, Fujitsu-Siemens and newer Medion BIOS from the MS-6318 as it was found out they use APIC --- src/machine/m_at_socket370.c | 27 --------------------------- 1 file changed, 27 deletions(-) diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 6627c70971..6602f2aedb 100644 --- a/src/machine/m_at_socket370.c +++ b/src/machine/m_at_socket370.c @@ -493,24 +493,6 @@ static const device_config_t ms6318_config[] = { .size = 262144, .files = { "roms/machines/ms6318/w6318vms.120", "" } }, - { - .name = "Award Modular BIOS v6.00PG - Revision 7.1B5E (Elonex OEM)", - .internal_name = "ms6318_715", - .bios_type = BIOS_NORMAL, - .files_no = 1, - .local = 0, - .size = 262144, - .files = { "roms/machines/ms6318/w6318ve1.715", "" } - }, - { - .name = "Award Modular BIOS v6.00PG - Revision 1.0B9 (Fujitsu-Siemens OEM)", - .internal_name = "ms6318_109", - .bios_type = BIOS_NORMAL, - .files_no = 1, - .local = 0, - .size = 262144, - .files = { "roms/machines/ms6318/ms-6318-ver5.bin", "" } - }, { .name = "Award Modular BIOS v6.00PG - Revision 1.8 (HP Pavilion A7xx)", .internal_name = "ms6318_180", @@ -547,15 +529,6 @@ static const device_config_t ms6318_config[] = { .size = 262144, .files = { "roms/machines/ms6318/ms6318.bin", "" } }, - { - .name = "Award Modular BIOS v6.00PG - Revision 7.51 (Medion MD6318)", - .internal_name = "ms6318_751", - .bios_type = BIOS_NORMAL, - .files_no = 1, - .local = 0, - .size = 262144, - .files = { "roms/machines/ms6318/bios.rom", "" } - }, { .files_no = 0 } } }, From 4e7bb0488a5186aa09ab2072b8b610b19d1ff6ce Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Jan 2026 09:28:10 +0100 Subject: [PATCH 26/58] Hard reset dialog: Rely on clicked button instead of role. --- src/qt/qt_mainwindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 08c001ff78..f6195389c6 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1218,8 +1218,8 @@ MainWindow::on_actionHard_Reset_triggered() if (confirm_reset) { QMessageBox questionbox(QMessageBox::Icon::Question, "86Box", tr("Are you sure you want to hard reset the emulated machine?"), QMessageBox::NoButton, this); questionbox.addButton(tr("Reset"), QMessageBox::AcceptRole); - questionbox.addButton(tr("Don't reset"), QMessageBox::RejectRole); - const auto chkbox = new QCheckBox(tr("Don't show this message again")); + auto no_reset_button = questionbox.addButton(tr("Don't reset"), QMessageBox::RejectRole); + const auto chkbox = new QCheckBox(tr("Don't show this message again")); questionbox.setCheckBox(chkbox); chkbox->setChecked(!confirm_reset); @@ -1227,7 +1227,7 @@ MainWindow::on_actionHard_Reset_triggered() confirm_reset = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); - if (questionbox.result() == QDialog::Accepted) { + if (questionbox.clickedButton() == no_reset_button) { confirm_reset = true; return; } From 656d777377f8b40a2ddf34b5b38c473bf2a9191b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Jan 2026 09:43:48 +0100 Subject: [PATCH 27/58] Help message: Always output to terminal on non-Windows platforms. --- src/86box.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/86box.c b/src/86box.c index ce9a3d96ea..e791871633 100644 --- a/src/86box.c +++ b/src/86box.c @@ -742,10 +742,7 @@ pc_show_usage(char *s) #ifdef _WIN32 ui_msgbox(MBX_ANSI | ((s == NULL) ? MBX_INFO : MBX_WARNING), p); #else - if (s == NULL) - always_log("%s", p); - else - ui_msgbox(MBX_ANSI | MBX_WARNING, p); + always_log("%s", p); #endif } From c065c61217ccc94016ed8ff892ee06e5e923490a Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Jan 2026 09:46:15 +0100 Subject: [PATCH 28/58] Also always make it MBX_INFO on Windows. --- src/86box.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/86box.c b/src/86box.c index e791871633..d3d9d05c75 100644 --- a/src/86box.c +++ b/src/86box.c @@ -740,7 +740,7 @@ pc_show_usage(char *s) s); #ifdef _WIN32 - ui_msgbox(MBX_ANSI | ((s == NULL) ? MBX_INFO : MBX_WARNING), p); + ui_msgbox(MBX_ANSI | MBX_INFO, p); #else always_log("%s", p); #endif From 1c39c308b64f6b7ee6722cb76c8ad1c08030018b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 23 Jan 2026 09:47:41 +0100 Subject: [PATCH 29/58] And get rid of the now useless s parameter. --- src/86box.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/86box.c b/src/86box.c index d3d9d05c75..80244dc8b8 100644 --- a/src/86box.c +++ b/src/86box.c @@ -682,12 +682,12 @@ delete_nvr_file(uint8_t flash) extern void device_find_all_descs(void); static void -pc_show_usage(char *s) +pc_show_usage(void) { char p[8192] = { 0 }; sprintf(p, - "\n%sUsage: 86box [options] [cfg-file]\n\n" + "\nUsage: 86box [options] [cfg-file]\n\n" "Valid options are:\n\n" "-? or --help\t\t\t- show this information\n" "-A or --assetpath path\t\t- set 'path' to be asset path\n" @@ -736,8 +736,7 @@ pc_show_usage(char *s) "-Y or --donothing\t\t- do not show any UI or run the emulation\n" #endif "-Z or --lastvmpath\t\t- the last param. is VM path rather than config\n" - "\nA config file can be specified. If none is, the default file will be used.\n", - s); + "\nA config file can be specified. If none is, the default file will be used.\n"); #ifdef _WIN32 ui_msgbox(MBX_ANSI | MBX_INFO, p); @@ -842,7 +841,7 @@ pc_init(int argc, char *argv[]) } } - pc_show_usage(""); + pc_show_usage(); return 0; } else if (!strcasecmp(argv[c], "--lastvmpath") || !strcasecmp(argv[c], "-Z")) { lvmp = 1; From 774365d08a0289bb84ba4a0062137ccdf13f78cb Mon Sep 17 00:00:00 2001 From: Cacodemon345 Date: Fri, 23 Jan 2026 21:07:47 +0600 Subject: [PATCH 30/58] Vulkan: Always do RGB correction on Windows --- src/qt/qt_vulkanwindowrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index 52d42ebf4e..41f913a87f 100644 --- a/src/qt/qt_vulkanwindowrenderer.cpp +++ b/src/qt/qt_vulkanwindowrenderer.cpp @@ -900,7 +900,7 @@ VulkanWindowRenderer::onBlit(int buf_idx, int x, int y, int w, int h) strcat(path, fn); QImage image = this->grab(); -#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) && !defined(Q_OS_WINDOWS) image.save(path, "png"); #else image.rgbSwapped().save(path, "png"); From b92da6a157fa279b5d078b30919a0d4478c72dc9 Mon Sep 17 00:00:00 2001 From: BlueRain-debug Date: Thu, 22 Jan 2026 17:35:24 +0000 Subject: [PATCH 31/58] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1004 of 1004 strings) Translation: 86Box/86Box Translate-URL: https://weblate.86box.net/projects/86box/86box/zh_Hans/ --- src/qt/languages/zh-CN.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index a960d8b2d3..c922e207bd 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2026-01-18 19:18+0000\n" +"PO-Revision-Date: 2026-01-23 17:57+0000\n" "Last-Translator: BlueRain-debug \n" "Language-Team: Chinese (Simplified Han script) \n" @@ -2666,7 +2666,7 @@ msgid "&Unmute" msgstr "解除静音(&U)" msgid "Softfloat FPU" -msgstr "Softfloat FPU" +msgstr "软浮点FPU" msgid "High performance impact" msgstr "重大性能影响" From 8ec8057d7e32f6e2eed00aafe63a9830dfba8bbd Mon Sep 17 00:00:00 2001 From: kotochi98 <185547947+kotochi98@users.noreply.github.com> Date: Sat, 24 Jan 2026 13:49:46 +0300 Subject: [PATCH 32/58] Add the beta evaluation BIOS for the MiTAC 6110zu and set the R804 retail BIOS as the default --- src/machine/m_at_slot1.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 713ab09c05..cbd0cdec5f 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -1431,20 +1431,20 @@ static const device_config_t vei8_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "vei8", + .default_string = "6110zu", .default_int = 0, .file_filter = NULL, .spinner = { 0 }, .selection = { { 0 } }, .bios = { { - .name = "Award Modular BIOS v6.00PG - Revision QHW.10.01 (HP Sherwood-B)", - .internal_name = "vei8", + .name = "Award Modular BIOS v6.00PG - Revision 61100003 (beta)", + .internal_name = "6110zu0003", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 262144, - .files = { "roms/machines/vei8/QHW1001.BIN", "" } + .files = { "roms/machines/vei8/61100003.BIN", "" } }, { .name = "Award Modular BIOS v6.00PG - Revision R804", @@ -1455,6 +1455,15 @@ static const device_config_t vei8_config[] = { .size = 262144, .files = { "roms/machines/vei8/r804.bin", "" } }, + { + .name = "Award Modular BIOS v6.00PG - Revision QHW.10.01 (HP Sherwood-B)", + .internal_name = "vei8", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/vei8/QHW1001.BIN", "" } + }, { .files_no = 0 } } }, From 197348a43ffea8dc614603033333e1beb5c98583 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Jan 2026 16:10:08 +0100 Subject: [PATCH 33/58] PCI: Make PCI configuration reads and writes length-aware and fix the DC390 PCI device ID AND'ing with EEPROM DO. --- src/chipset/ali1435.c | 4 +- src/chipset/ali1489.c | 4 +- src/chipset/ali1531.c | 18 ++--- src/chipset/ali1541.c | 20 ++--- src/chipset/ali1543.c | 130 ++++++++++++++++----------------- src/chipset/ali1621.c | 8 +- src/chipset/ims8848.c | 4 +- src/chipset/intel_420ex.c | 26 +++---- src/chipset/intel_4x0.c | 40 +++++----- src/chipset/intel_i450kx.c | 16 ++-- src/chipset/intel_piix.c | 90 +++++++++++------------ src/chipset/intel_sio.c | 22 +++--- src/chipset/opti822.c | 5 +- src/chipset/sis_5511.c | 8 +- src/chipset/sis_5571.c | 8 +- src/chipset/sis_5581.c | 8 +- src/chipset/sis_5591.c | 8 +- src/chipset/sis_5600.c | 8 +- src/chipset/sis_85c496.c | 54 +++++++------- src/chipset/sis_85c50x.c | 38 +++++----- src/chipset/stpc.c | 20 ++--- src/chipset/umc_8886.c | 5 +- src/chipset/umc_8890.c | 4 +- src/chipset/umc_hb4.c | 4 +- src/chipset/via_apollo.c | 15 ++-- src/chipset/via_pipc.c | 46 ++++++------ src/chipset/via_vt82c505.c | 16 ++-- src/chipset/vl82c59x.c | 8 +- src/device/pci_bridge.c | 5 +- src/device/vfio.c | 100 ++++++++++++------------- src/disk/hdc_ide_cmd640.c | 5 +- src/disk/hdc_ide_cmd646.c | 5 +- src/disk/hdc_ide_rz1000.c | 5 +- src/disk/hdc_ide_w83769f.c | 5 +- src/include/86box/pci.h | 8 +- src/network/net_ne2000.c | 4 +- src/network/net_pcnet.c | 4 +- src/network/net_rtl8139.c | 4 +- src/network/net_tulip.c | 4 +- src/pci.c | 52 +++++++++---- src/pci_dummy.c | 4 +- src/scsi/scsi_buslogic.c | 4 +- src/scsi/scsi_ncr53c8xx.c | 4 +- src/scsi/scsi_pcscsi.c | 17 +++-- src/sound/snd_audiopci.c | 8 +- src/sound/snd_cmi8x38.c | 4 +- src/video/vid_ati_mach64.c | 4 +- src/video/vid_ati_mach8.c | 4 +- src/video/vid_bochs_vbe.c | 5 +- src/video/vid_chips_69000.c | 4 +- src/video/vid_cl54xx.c | 4 +- src/video/vid_et4000w32.c | 4 +- src/video/vid_mga.c | 4 +- src/video/vid_s3.c | 12 +-- src/video/vid_s3_virge.c | 4 +- src/video/vid_tgui9440.c | 4 +- src/video/vid_voodoo.c | 4 +- src/video/vid_voodoo_banshee.c | 4 +- 58 files changed, 485 insertions(+), 451 deletions(-) diff --git a/src/chipset/ali1435.c b/src/chipset/ali1435.c index aebd10f32a..6619e033c1 100644 --- a/src/chipset/ali1435.c +++ b/src/chipset/ali1435.c @@ -98,7 +98,7 @@ ali1435_update_irqs(ali1435_t *dev, int set) } static void -ali1435_pci_write(int func, int addr, uint8_t val, void *priv) +ali1435_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1435_t *dev = (ali1435_t *) priv; int irq; @@ -163,7 +163,7 @@ ali1435_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali1435_pci_read(int func, int addr, void *priv) +ali1435_pci_read(int func, int addr, UNUSED(int len), void *priv) { const ali1435_t *dev = (ali1435_t *) priv; uint8_t ret; diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 96ebd4a3d1..fdf0697ec9 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -411,7 +411,7 @@ ali1489_read(uint16_t addr, void *priv) } static void -ali1489_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1489_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1489_t *dev = (ali1489_t *) priv; @@ -434,7 +434,7 @@ ali1489_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1489_pci_read(UNUSED(int func), int addr, void *priv) +ali1489_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1489_t *dev = (ali1489_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index 1603dbca4a..b57fe16063 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -132,7 +132,7 @@ ali1531_shadow_recalc(UNUSED(int cur_reg), ali1531_t *dev) } static void -ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1531_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1531_t *dev = (ali1531_t *) priv; @@ -298,7 +298,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1531_read(UNUSED(int func), int addr, void *priv) +ali1531_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1531_t *dev = (ali1531_t *) priv; uint8_t ret = 0xff; @@ -341,18 +341,18 @@ ali1531_reset(void *priv) dev->pci_conf[0x5a] = 0x20; dev->pci_conf[0x70] = 0x22; - ali1531_write(0, 0x42, 0x00, dev); - ali1531_write(0, 0x43, 0x00, dev); + ali1531_write(0, 0x42, 1, 0x00, dev); + ali1531_write(0, 0x43, 1, 0x00, dev); - ali1531_write(0, 0x47, 0x00, dev); - ali1531_write(0, 0x48, 0x00, dev); + ali1531_write(0, 0x47, 1, 0x00, dev); + ali1531_write(0, 0x48, 1, 0x00, dev); for (uint8_t i = 0; i < 4; i++) - ali1531_write(0, 0x4c + i, 0x00, dev); + ali1531_write(0, 0x4c + i, 1, 0x00, dev); for (uint8_t i = 0; i < 16; i += 2) { - ali1531_write(0, 0x60 + i, 0x08, dev); - ali1531_write(0, 0x61 + i, 0x40, dev); + ali1531_write(0, 0x60 + i, 1, 0x08, dev); + ali1531_write(0, 0x61 + i, 1, 0x40, dev); } } diff --git a/src/chipset/ali1541.c b/src/chipset/ali1541.c index 1506d880ab..02fd51c0ba 100644 --- a/src/chipset/ali1541.c +++ b/src/chipset/ali1541.c @@ -177,7 +177,7 @@ ali1541_mask_bar(ali1541_t *dev) } static void -ali1541_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1541_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1541_t *dev = (ali1541_t *) priv; @@ -562,7 +562,7 @@ ali1541_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1541_read(UNUSED(int func), int addr, void *priv) +ali1541_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1541_t *dev = (ali1541_t *) priv; uint8_t ret = 0xff; @@ -613,20 +613,20 @@ ali1541_reset(void *priv) dev->pci_conf[0xe0] = 0x01; cpu_cache_int_enabled = 1; - ali1541_write(0, 0x42, 0x00, dev); + ali1541_write(0, 0x42, 1, 0x00, dev); - ali1541_write(0, 0x54, 0x00, dev); - ali1541_write(0, 0x55, 0x00, dev); + ali1541_write(0, 0x54, 1, 0x00, dev); + ali1541_write(0, 0x55, 1, 0x00, dev); for (uint8_t i = 0; i < 4; i++) - ali1541_write(0, 0x56 + i, 0x00, dev); + ali1541_write(0, 0x56 + i, 1, 0x00, dev); - ali1541_write(0, 0x60, 0x07, dev); - ali1541_write(0, 0x61, 0x40, dev); + ali1541_write(0, 0x60, 1, 0x07, dev); + ali1541_write(0, 0x61, 1, 0x40, dev); for (uint8_t i = 0; i < 14; i += 2) { - ali1541_write(0, 0x62 + i, 0x00, dev); - ali1541_write(0, 0x63 + i, 0x00, dev); + ali1541_write(0, 0x62 + i, 1, 0x00, dev); + ali1541_write(0, 0x63 + i, 1, 0x00, dev); } } diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 8ef8e6a204..3d5ddf603f 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -112,13 +112,13 @@ ali1533_ddma_handler(UNUSED(ali1543_t *dev)) static void ali5229_ide_handler(ali1543_t *dev); static void ali5229_ide_irq_handler(ali1543_t *dev); -static void ali5229_write(int func, int addr, uint8_t val, void *priv); +static void ali5229_write(int func, int addr, int len, uint8_t val, void *priv); -static void ali7101_write(int func, int addr, uint8_t val, void *priv); -static uint8_t ali7101_read(int func, int addr, void *priv); +static void ali7101_write(int func, int addr, int len, uint8_t val, void *priv); +static uint8_t ali7101_read(int func, int addr, int len, void *priv); static void -ali1533_write(int func, int addr, uint8_t val, void *priv) +ali1533_write(int func, int addr, int len, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M1533: dev->pci_conf[%02x] = %02x\n", addr, val); @@ -453,7 +453,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x7c ... 0xff: if ((dev->type == 1) && !dev->pmu_dev_enable) { dev->pmu_dev_enable = 1; - ali7101_write(func, addr, val, priv); + ali7101_write(func, addr, len, val, priv); dev->pmu_dev_enable = 0; } break; @@ -464,7 +464,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali1533_read(int func, int addr, void *priv) +ali1533_read(int func, int addr, int len, void *priv) { ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -478,7 +478,7 @@ ali1533_read(int func, int addr, void *priv) ret = (ret & 0xbf) | (dev->ide_dev_enable ? 0x40 : 0x00); else if ((dev->type == 1) && ((addr >= 0x7c) && (addr <= 0xff)) && !dev->pmu_dev_enable) { dev->pmu_dev_enable = 1; - ret = ali7101_read(func, addr, priv); + ret = ali7101_read(func, addr, len, priv); dev->pmu_dev_enable = 0; } } @@ -690,23 +690,23 @@ ali5229_chip_reset(ali1543_t *dev) dev->ide_conf[0x4f] = 0x1a; } - ali5229_write(0, 0x04, 0x05, dev); - ali5229_write(0, 0x10, 0xf1, dev); - ali5229_write(0, 0x11, 0x01, dev); - ali5229_write(0, 0x14, 0xf5, dev); - ali5229_write(0, 0x15, 0x03, dev); - ali5229_write(0, 0x18, 0x71, dev); - ali5229_write(0, 0x19, 0x01, dev); - ali5229_write(0, 0x1a, 0x75, dev); - ali5229_write(0, 0x1b, 0x03, dev); - ali5229_write(0, 0x20, 0x01, dev); - ali5229_write(0, 0x21, 0xf0, dev); - ali5229_write(0, 0x4d, 0x00, dev); + ali5229_write(0, 0x04, 1, 0x05, dev); + ali5229_write(0, 0x10, 1, 0xf1, dev); + ali5229_write(0, 0x11, 1, 0x01, dev); + ali5229_write(0, 0x14, 1, 0xf5, dev); + ali5229_write(0, 0x15, 1, 0x03, dev); + ali5229_write(0, 0x18, 1, 0x71, dev); + ali5229_write(0, 0x19, 1, 0x01, dev); + ali5229_write(0, 0x1a, 1, 0x75, dev); + ali5229_write(0, 0x1b, 1, 0x03, dev); + ali5229_write(0, 0x20, 1, 0x01, dev); + ali5229_write(0, 0x21, 1, 0xf0, dev); + ali5229_write(0, 0x4d, 1, 0x00, dev); dev->ide_conf[0x09] = 0xfa; - ali5229_write(0, 0x09, 0xfa, dev); - ali5229_write(0, 0x52, 0x00, dev); + ali5229_write(0, 0x09, 1, 0xfa, dev); + ali5229_write(0, 0x52, 1, 0x00, dev); - ali5229_write(0, 0x50, 0x02, dev); + ali5229_write(0, 0x50, 1, 0x02, dev); sff_set_slot(dev->ide_controller[0], dev->ide_slot); sff_set_slot(dev->ide_controller[1], dev->ide_slot); @@ -716,7 +716,7 @@ ali5229_chip_reset(ali1543_t *dev) } static void -ali5229_write(int func, int addr, uint8_t val, void *priv) +ali5229_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M5229: [W] dev->ide_conf[%02x] = %02x\n", addr, val); @@ -885,7 +885,7 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali5229_read(int func, int addr, void *priv) +ali5229_read(int func, int addr, UNUSED(int len), void *priv) { const ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -908,7 +908,7 @@ ali5229_read(int func, int addr, void *priv) } static void -ali5237_write(int func, int addr, uint8_t val, void *priv) +ali5237_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M5237: dev->usb_conf[%02x] = %02x\n", addr, val); @@ -975,7 +975,7 @@ ali5237_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali5237_read(int func, int addr, void *priv) +ali5237_read(int func, int addr, UNUSED(int len), void *priv) { const ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -987,7 +987,7 @@ ali5237_read(int func, int addr, void *priv) } static void -ali7101_write(int func, int addr, uint8_t val, void *priv) +ali7101_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M7101: [W] dev->pmu_conf[%02x] = %02x\n", addr, val); @@ -1408,7 +1408,7 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali7101_read(int func, int addr, void *priv) +ali7101_read(int func, int addr, UNUSED(int len), void *priv) { ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -1516,11 +1516,11 @@ ali1543_reset(void *priv) dev->usb_conf[0x0b] = 0x0c; dev->usb_conf[0x3d] = 0x01; - ali5237_write(0, 0x04, 0x00, dev); - ali5237_write(0, 0x10, 0x00, dev); - ali5237_write(0, 0x11, 0x00, dev); - ali5237_write(0, 0x12, 0x00, dev); - ali5237_write(0, 0x13, 0x00, dev); + ali5237_write(0, 0x04, 1, 0x00, dev); + ali5237_write(0, 0x10, 1, 0x00, dev); + ali5237_write(0, 0x11, 1, 0x00, dev); + ali5237_write(0, 0x12, 1, 0x00, dev); + ali5237_write(0, 0x13, 1, 0x00, dev); /* M7101 */ memset(dev->pmu_conf, 0x00, sizeof(dev->pmu_conf)); @@ -1536,26 +1536,26 @@ ali1543_reset(void *priv) acpi_set_slot(dev->acpi, dev->pmu_slot); acpi_set_nvr(dev->acpi, dev->nvr); - ali7101_write(0, 0x04, 0x0f, dev); - ali7101_write(0, 0x10, 0x01, dev); - ali7101_write(0, 0x11, 0x00, dev); - ali7101_write(0, 0x12, 0x00, dev); - ali7101_write(0, 0x13, 0x00, dev); - ali7101_write(0, 0x14, 0x01, dev); - ali7101_write(0, 0x15, 0x00, dev); - ali7101_write(0, 0x16, 0x00, dev); - ali7101_write(0, 0x17, 0x00, dev); - ali7101_write(0, 0x40, 0x00, dev); - ali7101_write(0, 0x41, 0x00, dev); - ali7101_write(0, 0x42, 0x00, dev); - ali7101_write(0, 0x43, 0x00, dev); - ali7101_write(0, 0x77, 0x00, dev); - ali7101_write(0, 0xbd, 0x00, dev); - ali7101_write(0, 0xc0, 0x00, dev); - ali7101_write(0, 0xc1, 0x00, dev); - ali7101_write(0, 0xc2, 0x00, dev); - ali7101_write(0, 0xc3, 0x00, dev); - ali7101_write(0, 0xe0, 0x00, dev); + ali7101_write(0, 0x04, 1, 0x0f, dev); + ali7101_write(0, 0x10, 1, 0x01, dev); + ali7101_write(0, 0x11, 1, 0x00, dev); + ali7101_write(0, 0x12, 1, 0x00, dev); + ali7101_write(0, 0x13, 1, 0x00, dev); + ali7101_write(0, 0x14, 1, 0x01, dev); + ali7101_write(0, 0x15, 1, 0x00, dev); + ali7101_write(0, 0x16, 1, 0x00, dev); + ali7101_write(0, 0x17, 1, 0x00, dev); + ali7101_write(0, 0x40, 1, 0x00, dev); + ali7101_write(0, 0x41, 1, 0x00, dev); + ali7101_write(0, 0x42, 1, 0x00, dev); + ali7101_write(0, 0x43, 1, 0x00, dev); + ali7101_write(0, 0x77, 1, 0x00, dev); + ali7101_write(0, 0xbd, 1, 0x00, dev); + ali7101_write(0, 0xc0, 1, 0x00, dev); + ali7101_write(0, 0xc1, 1, 0x00, dev); + ali7101_write(0, 0xc2, 1, 0x00, dev); + ali7101_write(0, 0xc3, 1, 0x00, dev); + ali7101_write(0, 0xe0, 1, 0x00, dev); /* Do the bridge last due to device deactivations. */ /* M1533 */ @@ -1570,19 +1570,19 @@ ali1543_reset(void *priv) dev->pci_conf[0x0a] = 0x01; dev->pci_conf[0x0b] = 0x06; - ali1533_write(0, 0x41, 0x00, dev); /* Disables the keyboard and mouse IRQ latch. */ - ali1533_write(0, 0x48, 0x00, dev); /* Disables all IRQ's. */ - ali1533_write(0, 0x44, 0x00, dev); - ali1533_write(0, 0x4d, 0x00, dev); - ali1533_write(0, 0x53, 0x00, dev); - ali1533_write(0, 0x58, 0x00, dev); - ali1533_write(0, 0x5f, 0x00, dev); - ali1533_write(0, 0x72, 0x00, dev); - ali1533_write(0, 0x74, 0x00, dev); - ali1533_write(0, 0x75, 0x00, dev); - ali1533_write(0, 0x76, 0x00, dev); + ali1533_write(0, 0x41, 1, 0x00, dev); /* Disables the keyboard and mouse IRQ latch. */ + ali1533_write(0, 0x48, 1, 0x00, dev); /* Disables all IRQ's. */ + ali1533_write(0, 0x44, 1, 0x00, dev); + ali1533_write(0, 0x4d, 1, 0x00, dev); + ali1533_write(0, 0x53, 1, 0x00, dev); + ali1533_write(0, 0x58, 1, 0x00, dev); + ali1533_write(0, 0x5f, 1, 0x00, dev); + ali1533_write(0, 0x72, 1, 0x00, dev); + ali1533_write(0, 0x74, 1, 0x00, dev); + ali1533_write(0, 0x75, 1, 0x00, dev); + ali1533_write(0, 0x76, 1, 0x00, dev); if (dev->type == 1) - ali1533_write(0, 0x78, 0x00, dev); + ali1533_write(0, 0x78, 1, 0x00, dev); unmask_a20_in_smm = 1; } diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c index 95602496c3..217c1b865a 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -255,7 +255,7 @@ ali1621_mask_bar(ali1621_t *dev) } static void -ali1621_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1621_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1621_t *dev = (ali1621_t *) priv; @@ -581,7 +581,7 @@ ali1621_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1621_read(UNUSED(int func), int addr, void *priv) +ali1621_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1621_t *dev = (ali1621_t *) priv; uint8_t ret = 0xff; @@ -647,10 +647,10 @@ ali1621_reset(void *priv) dev->pci_conf[0xf2] = dev->pci_conf[0xf6] = dev->pci_conf[0xfa] = dev->pci_conf[0xfe] = 0x21; dev->pci_conf[0xf3] = dev->pci_conf[0xf7] = dev->pci_conf[0xfb] = dev->pci_conf[0xff] = 0x43; - ali1621_write(0, 0x83, 0x08, dev); + ali1621_write(0, 0x83, 1, 0x08, dev); for (uint8_t i = 0; i < 4; i++) - ali1621_write(0, 0x84 + i, 0x00, dev); + ali1621_write(0, 0x84 + i, 1, 0x00, dev); } static void diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index 13fed304b6..16625f3a1e 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -292,7 +292,7 @@ ims8848_read(uint16_t addr, void *priv) } static void -ims8849_pci_write(int func, int addr, uint8_t val, void *priv) +ims8849_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ims8848_t *dev = (ims8848_t *) priv; @@ -326,7 +326,7 @@ ims8849_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ims8849_pci_read(int func, int addr, void *priv) +ims8849_pci_read(int func, UNUSED(int len), int addr, void *priv) { const ims8848_t *dev = (ims8848_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index daa55c72c9..67e2ae0699 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -183,7 +183,7 @@ i420ex_drb_recalc(i420ex_t *dev) static void -i420ex_write(int func, int addr, uint8_t val, void *priv) +i420ex_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i420ex_t *dev = (i420ex_t *) priv; @@ -397,7 +397,7 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -i420ex_read(int func, int addr, void *priv) +i420ex_read(int func, int addr, UNUSED(int len), void *priv) { const i420ex_t *dev = (i420ex_t *) priv; uint8_t ret; @@ -472,31 +472,31 @@ i420ex_reset(void *priv) { i420ex_t *dev = (i420ex_t *) priv; - i420ex_write(0, 0x48, 0x00, priv); + i420ex_write(0, 0x48, 1, 0x00, priv); /* Disable the PIC mouse latch. */ - i420ex_write(0, 0x4e, 0x03, priv); + i420ex_write(0, 0x4e, 1, 0x03, priv); for (uint8_t i = 0; i < 7; i++) - i420ex_write(0, 0x59 + i, 0x00, priv); + i420ex_write(0, 0x59 + i, 1, 0x00, priv); for (uint8_t i = 0; i <= 4; i++) dev->regs[0x60 + i] = 0x01; dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */ dev->smram_locked = 0; - i420ex_write(0, 0x70, 0x00, priv); + i420ex_write(0, 0x70, 1, 0x00, priv); mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - i420ex_write(0, 0xa0, 0x08, priv); - i420ex_write(0, 0xa2, 0x00, priv); - i420ex_write(0, 0xa4, 0x00, priv); - i420ex_write(0, 0xa5, 0x00, priv); - i420ex_write(0, 0xa6, 0x00, priv); - i420ex_write(0, 0xa7, 0x00, priv); - i420ex_write(0, 0xa8, 0x0f, priv); + i420ex_write(0, 0xa0, 1, 0x08, priv); + i420ex_write(0, 0xa2, 1, 0x00, priv); + i420ex_write(0, 0xa4, 1, 0x00, priv); + i420ex_write(0, 0xa5, 1, 0x00, priv); + i420ex_write(0, 0xa6, 1, 0x00, priv); + i420ex_write(0, 0xa7, 1, 0x00, priv); + i420ex_write(0, 0xa8, 1, 0x0f, priv); } static void diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 18f4ee66a9..48627e39b5 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -243,7 +243,7 @@ pm2_cntrl_write(UNUSED(uint16_t addr), uint8_t val, void *priv) } static void -i4x0_write(int func, int addr, uint8_t val, void *priv) +i4x0_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i4x0_t *dev = (i4x0_t *) priv; uint8_t *regs = (uint8_t *) dev->regs; @@ -1535,7 +1535,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -i4x0_read(int func, int addr, void *priv) +i4x0_read(int func, int addr, UNUSED(int len), void *priv) { i4x0_t *dev = (i4x0_t *) priv; uint8_t ret = 0xff; @@ -1563,12 +1563,12 @@ i4x0_reset(void *priv) memset(dev->regs_locked, 0x00, 256 * sizeof(uint8_t)); if (dev->type >= INTEL_430FX) - i4x0_write(0, 0x59, 0x00, priv); + i4x0_write(0, 0x59, 1, 0x00, priv); else - i4x0_write(0, 0x59, 0x0f, priv); + i4x0_write(0, 0x59, 1, 0x0f, priv); for (uint8_t i = 0; i < 6; i++) - i4x0_write(0, 0x5a + i, 0x00, priv); + i4x0_write(0, 0x5a + i, 1, 0x00, priv); for (uint8_t i = 0; i <= dev->max_drb; i++) dev->regs[0x60 + i] = dev->drb_default; @@ -1582,18 +1582,18 @@ i4x0_reset(void *priv) if (dev->type >= INTEL_430FX) { dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ - i4x0_write(0, 0x72, 0x02, priv); + i4x0_write(0, 0x72, 1, 0x02, priv); } else if (dev->type >= INTEL_430LX) { dev->regs[0x72] &= 0xf7; /* Forcibly unlock the SMRAM register. */ - i4x0_write(0, 0x72, 0x00, priv); + i4x0_write(0, 0x72, 1, 0x00, priv); } else { dev->regs[0x57] &= 0xef; /* Forcibly unlock the SMRAM register. */ - i4x0_write(0, 0x57, 0x02, priv); + i4x0_write(0, 0x57, 1, 0x02, priv); } if ((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) { i4x0_write(0, (dev->type >= INTEL_440BX) ? 0x73 : 0x71, - (dev->type >= INTEL_440BX) ? 0x38 : 0x00, priv); + 1, (dev->type >= INTEL_440BX) ? 0x38 : 0x00, priv); } } @@ -1932,24 +1932,24 @@ i4x0_init(const device_t *info) else if (dev->type >= INTEL_440LX) cpu_set_agp_speed(cpu_busspeed); - i4x0_write(regs[0x59], 0x59, 0x00, dev); - i4x0_write(regs[0x5a], 0x5a, 0x00, dev); - i4x0_write(regs[0x5b], 0x5b, 0x00, dev); - i4x0_write(regs[0x5c], 0x5c, 0x00, dev); - i4x0_write(regs[0x5d], 0x5d, 0x00, dev); - i4x0_write(regs[0x5e], 0x5e, 0x00, dev); - i4x0_write(regs[0x5f], 0x5f, 0x00, dev); + i4x0_write(regs[0x59], 0x59, 1, 0x00, dev); + i4x0_write(regs[0x5a], 0x5a, 1, 0x00, dev); + i4x0_write(regs[0x5b], 0x5b, 1, 0x00, dev); + i4x0_write(regs[0x5c], 0x5c, 1, 0x00, dev); + i4x0_write(regs[0x5d], 0x5d, 1, 0x00, dev); + i4x0_write(regs[0x5e], 0x5e, 1, 0x00, dev); + i4x0_write(regs[0x5f], 0x5f, 1, 0x00, dev); if (dev->type >= INTEL_430FX) - i4x0_write(0, 0x72, 0x02, dev); + i4x0_write(0, 0x72, 1, 0x02, dev); else if (dev->type >= INTEL_430LX) - i4x0_write(0, 0x72, 0x00, dev); + i4x0_write(0, 0x72, 1, 0x00, dev); else - i4x0_write(0, 0x57, 0x02, dev); + i4x0_write(0, 0x57, 1, 0x02, dev); if ((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) { i4x0_write(0, (dev->type >= INTEL_440BX) ? 0x73 : 0x71, - (dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev); + 1, (dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev); } pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev, &dev->pci_slot); diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 34cc6a62f7..cb793179a5 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -126,7 +126,7 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus) } static void -pb_write(int func, int addr, uint8_t val, void *priv) +pb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; @@ -371,7 +371,7 @@ pb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -pb_read(int func, int addr, void *priv) +pb_read(int func, int addr, UNUSED(int len), void *priv) { const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; @@ -400,7 +400,7 @@ mc_fill_drbs(i450kx_t *dev) } static void -mc_write(int func, int addr, uint8_t val, void *priv) +mc_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; @@ -601,7 +601,7 @@ mc_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -mc_read(int func, int addr, void *priv) +mc_read(int func, int addr, UNUSED(int len), void *priv) { const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; @@ -707,9 +707,9 @@ i450kx_reset(void *priv) #endif i450kx_smram_recalc(dev, 1); i450kx_vid_buf_recalc(dev, 1); - pb_write(0, 0x59, 0x30, dev); + pb_write(0, 0x59, 1, 0x30, dev); for (i = 0x5a; i <= 0x5f; i++) - pb_write(0, i, 0x33, dev); + pb_write(0, i, 1, 0x33, dev); /* Defaults MC */ dev->mc_pci_conf[0x00] = 0x86; @@ -779,9 +779,9 @@ i450kx_reset(void *priv) i450kx_smram_recalc(dev, 0); i450kx_vid_buf_recalc(dev, 0); - mc_write(0, 0x59, 0x03, dev); + mc_write(0, 0x59, 1, 0x03, dev); for (i = 0x5a; i <= 0x5f; i++) - mc_write(0, i, 0x00, dev); + mc_write(0, i, 1, 0x00, dev); for (i = 0x60; i <= 0x6f; i++) dev->mc_pci_conf[i] = 0x01; } diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 9d4d88687d..9f78148699 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -464,7 +464,7 @@ piix_trap_update(void *priv) } static void -piix_write(int func, int addr, uint8_t val, void *priv) +piix_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { piix_t *dev = (piix_t *) priv; uint8_t *fregs; @@ -1192,7 +1192,7 @@ piix_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -piix_read(int func, int addr, void *priv) +piix_read(int func, int addr, UNUSED(int len), void *priv) { piix_t *dev = (piix_t *) priv; uint8_t ret = 0xff; @@ -1447,68 +1447,68 @@ piix_reset(void *priv) const piix_t *dev = (piix_t *) priv; if (dev->type > 3) { - piix_write(3, 0x04, 0x00, priv); - piix_write(3, 0x5b, 0x00, priv); + piix_write(3, 0x04, 1, 0x00, priv); + piix_write(3, 0x5b, 1, 0x00, priv); } else { - piix_write(0, 0xa0, 0x08, priv); - piix_write(0, 0xa2, 0x00, priv); - piix_write(0, 0xa4, 0x00, priv); - piix_write(0, 0xa5, 0x00, priv); - piix_write(0, 0xa6, 0x00, priv); - piix_write(0, 0xa7, 0x00, priv); - piix_write(0, 0xa8, 0x0f, priv); + piix_write(0, 0xa0, 1, 0x08, priv); + piix_write(0, 0xa2, 1, 0x00, priv); + piix_write(0, 0xa4, 1, 0x00, priv); + piix_write(0, 0xa5, 1, 0x00, priv); + piix_write(0, 0xa6, 1, 0x00, priv); + piix_write(0, 0xa7, 1, 0x00, priv); + piix_write(0, 0xa8, 1, 0x0f, priv); } /* Disable the PIC mouse latch. */ - piix_write(0, 0x4e, 0x03, priv); + piix_write(0, 0x4e, 1, 0x03, priv); if (dev->type == 5) - piix_write(0, 0xe1, 0x40, priv); - piix_write(1, 0x04, 0x00, priv); + piix_write(0, 0xe1, 1, 0x40, priv); + piix_write(1, 0x04, 1, 0x00, priv); if (dev->type == 5) { - piix_write(1, 0x09, 0x8a, priv); - piix_write(1, 0x10, 0xf1, priv); - piix_write(1, 0x11, 0x01, priv); - piix_write(1, 0x14, 0xf5, priv); - piix_write(1, 0x15, 0x03, priv); - piix_write(1, 0x18, 0x71, priv); - piix_write(1, 0x19, 0x01, priv); - piix_write(1, 0x1c, 0x75, priv); - piix_write(1, 0x1d, 0x03, priv); + piix_write(1, 0x09, 1, 0x8a, priv); + piix_write(1, 0x10, 1, 0xf1, priv); + piix_write(1, 0x11, 1, 0x01, priv); + piix_write(1, 0x14, 1, 0xf5, priv); + piix_write(1, 0x15, 1, 0x03, priv); + piix_write(1, 0x18, 1, 0x71, priv); + piix_write(1, 0x19, 1, 0x01, priv); + piix_write(1, 0x1c, 1, 0x75, priv); + piix_write(1, 0x1d, 1, 0x03, priv); } else - piix_write(1, 0x09, 0x80, priv); - piix_write(1, 0x20, 0x01, priv); - piix_write(1, 0x21, 0x00, priv); - piix_write(1, 0x41, 0x00, priv); - piix_write(1, 0x43, 0x00, priv); + piix_write(1, 0x09, 1, 0x80, priv); + piix_write(1, 0x20, 1, 0x01, priv); + piix_write(1, 0x21, 1, 0x00, priv); + piix_write(1, 0x41, 1, 0x00, priv); + piix_write(1, 0x43, 1, 0x00, priv); ide_pri_disable(); ide_sec_disable(); if (dev->type >= 3) { - piix_write(2, 0x04, 0x00, priv); + piix_write(2, 0x04, 1, 0x00, priv); if (dev->type == 5) { - piix_write(2, 0x10, 0x00, priv); - piix_write(2, 0x11, 0x00, priv); - piix_write(2, 0x12, 0x00, priv); - piix_write(2, 0x13, 0x00, priv); + piix_write(2, 0x10, 1, 0x00, priv); + piix_write(2, 0x11, 1, 0x00, priv); + piix_write(2, 0x12, 1, 0x00, priv); + piix_write(2, 0x13, 1, 0x00, priv); } else { - piix_write(2, 0x20, 0x01, priv); - piix_write(2, 0x21, 0x00, priv); - piix_write(2, 0x22, 0x00, priv); - piix_write(2, 0x23, 0x00, priv); + piix_write(2, 0x20, 1, 0x01, priv); + piix_write(2, 0x21, 1, 0x00, priv); + piix_write(2, 0x22, 1, 0x00, priv); + piix_write(2, 0x23, 1, 0x00, priv); } } if (dev->type >= 4) { - piix_write(0, 0xb0, is_pentium ? 0x00 : 0x04, priv); - piix_write(3, 0x40, 0x01, priv); - piix_write(3, 0x41, 0x00, priv); - piix_write(3, 0x5b, 0x00, priv); - piix_write(3, 0x80, 0x00, priv); - piix_write(3, 0x90, 0x01, priv); - piix_write(3, 0x91, 0x00, priv); - piix_write(3, 0xd2, 0x00, priv); + piix_write(0, 0xb0, 1, is_pentium ? 0x00 : 0x04, priv); + piix_write(3, 0x40, 1, 0x01, priv); + piix_write(3, 0x41, 1, 0x00, priv); + piix_write(3, 0x5b, 1, 0x00, priv); + piix_write(3, 0x80, 1, 0x00, priv); + piix_write(3, 0x90, 1, 0x01, priv); + piix_write(3, 0x91, 1, 0x00, priv); + piix_write(3, 0xd2, 1, 0x00, priv); } sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 739785acb7..c28fa5471e 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -135,7 +135,7 @@ sio_timer_readw(uint16_t addr, void *priv) } static void -sio_write(int func, int addr, uint8_t val, void *priv) +sio_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { sio_t *dev = (sio_t *) priv; uint8_t old; @@ -324,7 +324,7 @@ sio_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sio_read(int func, int addr, void *priv) +sio_read(int func, int addr, UNUSED(int len), void *priv) { const sio_t *dev = (sio_t *) priv; uint8_t ret; @@ -473,20 +473,20 @@ sio_reset(void *priv) const sio_t *dev = (sio_t *) priv; /* Disable the PIC mouse latch. */ - sio_write(0, 0x4d, 0x40, priv); + sio_write(0, 0x4d, 1, 0x40, priv); - sio_write(0, 0x57, 0x04, priv); + sio_write(0, 0x57, 1, 0x04, priv); dma_set_params(1, 0xffffffff); if (dev->id == 0x03) { - sio_write(0, 0xa0, 0x08, priv); - sio_write(0, 0xa2, 0x00, priv); - sio_write(0, 0xa4, 0x00, priv); - sio_write(0, 0xa5, 0x00, priv); - sio_write(0, 0xa6, 0x00, priv); - sio_write(0, 0xa7, 0x00, priv); - sio_write(0, 0xa8, 0x0f, priv); + sio_write(0, 0xa0, 1, 0x08, priv); + sio_write(0, 0xa2, 1, 0x00, priv); + sio_write(0, 0xa4, 1, 0x00, priv); + sio_write(0, 0xa5, 1, 0x00, priv); + sio_write(0, 0xa6, 1, 0x00, priv); + sio_write(0, 0xa7, 1, 0x00, priv); + sio_write(0, 0xa8, 1, 0x0f, priv); } } diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 2f416a1c27..2029a6b40c 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -48,7 +48,6 @@ typedef struct opti822_t { uint8_t pci_regs[256]; } opti822_t; -// #define ENABLE_OPTI822_LOG 1 #ifdef ENABLE_OPTI822_LOG int opti822_do_log = ENABLE_OPTI822_LOG; @@ -131,7 +130,7 @@ opti822_update_irqs(opti822_t *dev, int set) } static void -opti822_pci_write(int func, int addr, uint8_t val, void *priv) +opti822_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { opti822_t *dev = (opti822_t *) priv; int irq; @@ -336,7 +335,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -opti822_pci_read(int func, int addr, void *priv) +opti822_pci_read(int func, int addr, UNUSED(int len), void *priv) { const opti822_t *dev = (opti822_t *) priv; uint8_t ret; diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index 38fcfe717a..c22f798afc 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -76,7 +76,7 @@ typedef struct sis_5511_t { } sis_5511_t; static void -sis_5511_write(int func, int addr, uint8_t val, void *priv) +sis_5511_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; @@ -87,7 +87,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5511_read(int func, int addr, void *priv) +sis_5511_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; @@ -101,7 +101,7 @@ sis_5511_read(int func, int addr, void *priv) } static void -sis_5513_write(int func, int addr, uint8_t val, void *priv) +sis_5513_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; @@ -114,7 +114,7 @@ sis_5513_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5513_read(int func, int addr, void *priv) +sis_5513_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 02e86a98a8..824f1f3386 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -75,7 +75,7 @@ typedef struct sis_5571_t { } sis_5571_t; static void -sis_5571_write(int func, int addr, uint8_t val, void *priv) +sis_5571_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; @@ -86,7 +86,7 @@ sis_5571_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5571_read(int func, int addr, void *priv) +sis_5571_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; @@ -100,7 +100,7 @@ sis_5571_read(int func, int addr, void *priv) } static void -sis_5572_write(int func, int addr, uint8_t val, void *priv) +sis_5572_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; @@ -120,7 +120,7 @@ sis_5572_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5572_read(int func, int addr, void *priv) +sis_5572_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c index 525fe65980..ea54a407b2 100644 --- a/src/chipset/sis_5581.c +++ b/src/chipset/sis_5581.c @@ -75,7 +75,7 @@ typedef struct sis_5581_t { } sis_5581_t; static void -sis_5581_write(int func, int addr, uint8_t val, void *priv) +sis_5581_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; @@ -86,7 +86,7 @@ sis_5581_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5581_read(int func, int addr, void *priv) +sis_5581_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; uint8_t ret = 0xff; @@ -100,7 +100,7 @@ sis_5581_read(int func, int addr, void *priv) } static void -sis_5582_write(int func, int addr, uint8_t val, void *priv) +sis_5582_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; @@ -120,7 +120,7 @@ sis_5582_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5582_read(int func, int addr, void *priv) +sis_5582_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5591.c b/src/chipset/sis_5591.c index d814e0f749..48cbe97654 100644 --- a/src/chipset/sis_5591.c +++ b/src/chipset/sis_5591.c @@ -76,7 +76,7 @@ typedef struct sis_5591_t { } sis_5591_t; static void -sis_5591_write(int func, int addr, uint8_t val, void *priv) +sis_5591_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; @@ -89,7 +89,7 @@ sis_5591_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5591_read(int func, int addr, void *priv) +sis_5591_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; uint8_t ret = 0xff; @@ -105,7 +105,7 @@ sis_5591_read(int func, int addr, void *priv) } static void -sis_5595_write(int func, int addr, uint8_t val, void *priv) +sis_5595_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; @@ -125,7 +125,7 @@ sis_5595_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5595_read(int func, int addr, void *priv) +sis_5595_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5600.c b/src/chipset/sis_5600.c index 564243c68c..2610ea88fa 100644 --- a/src/chipset/sis_5600.c +++ b/src/chipset/sis_5600.c @@ -76,7 +76,7 @@ typedef struct sis_5600_t { } sis_5600_t; static void -sis_5600_write(int func, int addr, uint8_t val, void *priv) +sis_5600_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; @@ -89,7 +89,7 @@ sis_5600_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5600_read(int func, int addr, void *priv) +sis_5600_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; uint8_t ret = 0xff; @@ -105,7 +105,7 @@ sis_5600_read(int func, int addr, void *priv) } static void -sis_5595_write(int func, int addr, uint8_t val, void *priv) +sis_5595_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; @@ -125,7 +125,7 @@ sis_5595_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5595_read(int func, int addr, void *priv) +sis_5595_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index f2c1941d49..a04f016331 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -216,7 +216,7 @@ sis_85c496_drb_recalc(sis_85c496_t *dev) /* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */ static void -sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +sis_85c49x_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; uint8_t old; @@ -507,7 +507,7 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -sis_85c49x_pci_read(UNUSED(int func), int addr, void *priv) +sis_85c49x_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const sis_85c496_t *dev = (sis_85c496_t *) priv; uint8_t ret = dev->pci_conf[addr]; @@ -577,35 +577,35 @@ sis_85c496_reset(void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; - sis_85c49x_pci_write(0, 0x44, 0x00, dev); - sis_85c49x_pci_write(0, 0x45, 0x00, dev); - sis_85c49x_pci_write(0, 0x58, 0x00, dev); - sis_85c49x_pci_write(0, 0x59, 0x00, dev); - sis_85c49x_pci_write(0, 0x5a, 0x00, dev); - // sis_85c49x_pci_write(0, 0x5a, 0x06, dev); + sis_85c49x_pci_write(0, 0x44, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x45, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x58, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x59, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x5a, 1, 0x00, dev); + // sis_85c49x_pci_write(0, 0x5a, 1, 0x06, dev); for (uint8_t i = 0; i < 8; i++) dev->pci_conf[0x48 + i] = 0x02; - sis_85c49x_pci_write(0, 0x80, 0x00, dev); - sis_85c49x_pci_write(0, 0x81, 0x00, dev); - sis_85c49x_pci_write(0, 0x9e, 0x00, dev); - sis_85c49x_pci_write(0, 0x8d, 0x00, dev); - sis_85c49x_pci_write(0, 0xa0, 0xff, dev); - sis_85c49x_pci_write(0, 0xa1, 0xff, dev); - sis_85c49x_pci_write(0, 0xc0, 0x00, dev); - sis_85c49x_pci_write(0, 0xc1, 0x00, dev); - sis_85c49x_pci_write(0, 0xc2, 0x00, dev); - sis_85c49x_pci_write(0, 0xc3, 0x00, dev); - sis_85c49x_pci_write(0, 0xc8, 0x00, dev); - sis_85c49x_pci_write(0, 0xc9, 0x00, dev); - sis_85c49x_pci_write(0, 0xca, 0x00, dev); - sis_85c49x_pci_write(0, 0xcb, 0x00, dev); - - sis_85c49x_pci_write(0, 0xd0, 0x79, dev); - sis_85c49x_pci_write(0, 0xd1, 0xff, dev); - sis_85c49x_pci_write(0, 0xd0, 0x78, dev); - sis_85c49x_pci_write(0, 0xd4, 0x00, dev); + sis_85c49x_pci_write(0, 0x80, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x81, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x9e, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x8d, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xa0, 1, 0xff, dev); + sis_85c49x_pci_write(0, 0xa1, 1, 0xff, dev); + sis_85c49x_pci_write(0, 0xc0, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc1, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc2, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc3, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc8, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc9, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xca, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xcb, 1, 0x00, dev); + + sis_85c49x_pci_write(0, 0xd0, 1, 0x79, dev); + sis_85c49x_pci_write(0, 0xd1, 1, 0xff, dev); + sis_85c49x_pci_write(0, 0xd0, 1, 0x78, dev); + sis_85c49x_pci_write(0, 0xd4, 1, 0x00, dev); dev->pci_conf[0x67] = 0x00; dev->pci_conf[0xc6] = 0x00; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index e932ff6ca6..5eb3b518d9 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -199,7 +199,7 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev) } static void -sis_85c50x_write(int func, int addr, uint8_t val, void *priv) +sis_85c50x_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { sis_85c50x_t *dev = (sis_85c50x_t *) priv; @@ -311,7 +311,7 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_85c50x_read(int func, int addr, void *priv) +sis_85c50x_read(int func, int addr, UNUSED(int len), void *priv) { const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; @@ -344,7 +344,7 @@ sis_85c50x_ide_recalc(sis_85c50x_t *dev) } static void -sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) +sis_85c50x_sb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { sis_85c50x_t *dev = (sis_85c50x_t *) priv; @@ -393,7 +393,7 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_85c50x_sb_read(int func, int addr, void *priv) +sis_85c50x_sb_read(int func, int addr, UNUSED(int len), void *priv) { const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; @@ -553,17 +553,17 @@ sis_85c50x_reset(void *priv) dev->pci_conf[0x0a] = 0x00; dev->pci_conf[0x0b] = 0x06; - sis_85c50x_write(0, 0x51, 0x00, dev); - sis_85c50x_write(0, 0x53, 0x00, dev); - sis_85c50x_write(0, 0x54, 0x00, dev); - sis_85c50x_write(0, 0x55, 0x00, dev); - sis_85c50x_write(0, 0x56, 0x00, dev); - sis_85c50x_write(0, 0x5b, 0x00, dev); - sis_85c50x_write(0, 0x60, 0x00, dev); - sis_85c50x_write(0, 0x64, 0x00, dev); - sis_85c50x_write(0, 0x65, 0x00, dev); - sis_85c50x_write(0, 0x68, 0x00, dev); - sis_85c50x_write(0, 0x69, 0xff, dev); + sis_85c50x_write(0, 0x51, 1, 0x00, dev); + sis_85c50x_write(0, 0x53, 1, 0x00, dev); + sis_85c50x_write(0, 0x54, 1, 0x00, dev); + sis_85c50x_write(0, 0x55, 1, 0x00, dev); + sis_85c50x_write(0, 0x56, 1, 0x00, dev); + sis_85c50x_write(0, 0x5b, 1, 0x00, dev); + sis_85c50x_write(0, 0x60, 1, 0x00, dev); + sis_85c50x_write(0, 0x64, 1, 0x00, dev); + sis_85c50x_write(0, 0x65, 1, 0x00, dev); + sis_85c50x_write(0, 0x68, 1, 0x00, dev); + sis_85c50x_write(0, 0x69, 1, 0xff, dev); if (dev->type & 1) { for (uint8_t i = 0; i < 8; i++) @@ -586,10 +586,10 @@ sis_85c50x_reset(void *priv) dev->pci_conf_sb[0x0b] = 0x06; if (dev->type & 2) dev->pci_conf_sb[0x0e] = 0x80; - sis_85c50x_sb_write(0, 0x41, 0x80, dev); - sis_85c50x_sb_write(0, 0x42, 0x80, dev); - sis_85c50x_sb_write(0, 0x43, 0x80, dev); - sis_85c50x_sb_write(0, 0x44, 0x80, dev); + sis_85c50x_sb_write(0, 0x41, 1, 0x80, dev); + sis_85c50x_sb_write(0, 0x42, 1, 0x80, dev); + sis_85c50x_sb_write(0, 0x43, 1, 0x80, dev); + sis_85c50x_sb_write(0, 0x44, 1, 0x80, dev); if (dev->type & 2) { /* IDE (SiS 5503) */ diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 56eca8268d..e78a68c20b 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -213,7 +213,7 @@ stpc_localbus_read(uint16_t addr, void *priv) } static void -stpc_nb_write(int func, int addr, uint8_t val, void *priv) +stpc_nb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; @@ -260,7 +260,7 @@ stpc_nb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_nb_read(int func, int addr, void *priv) +stpc_nb_read(int func, int addr, UNUSED(int len), void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; @@ -337,7 +337,7 @@ stpc_ide_bm_handlers(stpc_t *dev) } static void -stpc_ide_write(int func, int addr, uint8_t val, void *priv) +stpc_ide_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; @@ -445,7 +445,7 @@ stpc_ide_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_ide_read(int func, int addr, void *priv) +stpc_ide_read(int func, int addr, UNUSED(int len), void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; @@ -466,12 +466,12 @@ stpc_ide_read(int func, int addr, void *priv) } static void -stpc_isab_write(int func, int addr, uint8_t val, void *priv) +stpc_isab_write(int func, int addr, int len, uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; if ((func == 1) && (dev->local != STPC_ATLAS)) { - stpc_ide_write(0, addr, val, priv); + stpc_ide_write(0, addr, len, val, priv); return; } @@ -507,13 +507,13 @@ stpc_isab_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_isab_read(int func, int addr, void *priv) +stpc_isab_read(int func, int addr, int len, void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; if ((func == 1) && (dev->local != STPC_ATLAS)) - ret = stpc_ide_read(0, addr, priv); + ret = stpc_ide_read(0, addr, len, priv); else if (func > 0) ret = 0xff; else @@ -524,7 +524,7 @@ stpc_isab_read(int func, int addr, void *priv) } static void -stpc_usb_write(int func, int addr, uint8_t val, void *priv) +stpc_usb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; @@ -571,7 +571,7 @@ stpc_usb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_usb_read(int func, int addr, void *priv) +stpc_usb_read(int func, int addr, UNUSED(int len), void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index 3725394c3d..7350f50584 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -84,6 +84,7 @@ #include <86box/machine.h> #include <86box/pic.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -187,7 +188,7 @@ umc_8886_irq_recalc(umc_8886_t *dev) } static void -umc_8886_write(int func, int addr, uint8_t val, void *priv) +umc_8886_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { umc_8886_t *dev = (umc_8886_t *) priv; @@ -293,7 +294,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -umc_8886_read(int func, int addr, void *priv) +umc_8886_read(int func, int addr, UNUSED(int len), void *priv) { const umc_8886_t *dev = (umc_8886_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c index cb69ce6a8d..1be55de887 100644 --- a/src/chipset/umc_8890.c +++ b/src/chipset/umc_8890.c @@ -119,7 +119,7 @@ um8890_smram(umc_8890_t *dev) } static void -um8890_write(int func, int addr, uint8_t val, void *priv) +um8890_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { umc_8890_t *dev = (umc_8890_t *)priv; @@ -158,7 +158,7 @@ um8890_write(int func, int addr, uint8_t val, void *priv) static uint8_t -um8890_read(int func, int addr, void *priv) +um8890_read(int func, int addr, UNUSED(int len), void *priv) { umc_8890_t *dev = (umc_8890_t *)priv; uint8_t ret = 0xff; diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index 55901b32ea..ae62da1664 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -275,7 +275,7 @@ hb4_smram(hb4_t *dev) } static void -hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) +hb4_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { hb4_t *dev = (hb4_t *) priv; @@ -336,7 +336,7 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -hb4_read(int func, int addr, void *priv) +hb4_read(int func, int addr, UNUSED(int len), void *priv) { const hb4_t *dev = (hb4_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 3236bbbbe8..b4646ba04f 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -29,6 +29,7 @@ #include <86box/device.h> #include <86box/pci.h> #include <86box/chipset.h> +#include <86box/plat_unused.h> #include <86box/spd.h> #include <86box/agpgart.h> @@ -225,7 +226,7 @@ via_apollo_setup(via_apollo_t *dev) } static void -via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) +via_apollo_host_bridge_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { via_apollo_t *dev = (via_apollo_t *) priv; if (func) @@ -684,7 +685,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -via_apollo_read(int func, int addr, void *priv) +via_apollo_read(int func, int addr, UNUSED(int len), void *priv) { const via_apollo_t *dev = (via_apollo_t *) priv; uint8_t ret = 0xff; @@ -701,11 +702,11 @@ via_apollo_read(int func, int addr, void *priv) } static void -via_apollo_write(int func, int addr, uint8_t val, void *priv) +via_apollo_write(int func, int addr, int len, uint8_t val, void *priv) { switch (func) { case 0: - via_apollo_host_bridge_write(func, addr, val, priv); + via_apollo_host_bridge_write(func, addr, len, val, priv); break; default: break; @@ -715,9 +716,9 @@ via_apollo_write(int func, int addr, uint8_t val, void *priv) static void via_apollo_reset(void *priv) { - via_apollo_write(0, 0x61, 0x00, priv); - via_apollo_write(0, 0x62, 0x00, priv); - via_apollo_write(0, 0x63, 0x00, priv); + via_apollo_write(0, 0x61, 1, 0x00, priv); + via_apollo_write(0, 0x62, 1, 0x00, priv); + via_apollo_write(0, 0x63, 1, 0x00, priv); } static void * diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index a476b9b990..a5883791ec 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -170,8 +170,8 @@ pipc_log(const char *fmt, ...) static void pipc_sgd_handlers(pipc_t *dev, uint8_t modem); static void pipc_codec_handlers(pipc_t *dev, uint8_t modem); static void pipc_sb_handlers(pipc_t *dev, uint8_t modem); -static uint8_t pipc_read(int func, int addr, void *priv); -static void pipc_write(int func, int addr, uint8_t val, void *priv); +static uint8_t pipc_read(int func, int addr, int len, void *priv); +static void pipc_write(int func, int addr, int len, uint8_t val, void *priv); static void pipc_io_trap_pact(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), void *priv) @@ -930,7 +930,7 @@ pipc_sb_get_buffer(int32_t *buffer, int len, void *priv) } static uint8_t -pipc_read(int func, int addr, void *priv) +pipc_read(int func, int addr, UNUSED(int len), void *priv) { pipc_t *dev = (pipc_t *) priv; uint8_t ret = 0xff; @@ -1026,7 +1026,7 @@ pipc_ddma_update(pipc_t *dev, int addr) } static void -pipc_write(int func, int addr, uint8_t val, void *priv) +pipc_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { pipc_t *dev = (pipc_t *) priv; int c; @@ -1661,34 +1661,34 @@ pipc_reset(void *priv) pipc_t *dev = (pipc_t *) priv; uint8_t pm_func = dev->usb[1] ? 4 : 3; - pipc_write(pm_func, 0x41, 0x00, priv); - pipc_write(pm_func, 0x48, 0x01, priv); - pipc_write(pm_func, 0x49, 0x00, priv); + pipc_write(pm_func, 0x41, 1, 0x00, priv); + pipc_write(pm_func, 0x48, 1, 0x01, priv); + pipc_write(pm_func, 0x49, 1, 0x00, priv); dev->power_regs[0x42] = ((dev->local >> 16) == VIA_PIPC_586) ? 0x00 : 0x50; acpi_set_irq_line(dev->acpi, 0x00); - pipc_write(1, 0x04, 0x80, priv); - pipc_write(1, 0x09, 0x85, priv); - pipc_write(1, 0x10, 0xf1, priv); - pipc_write(1, 0x11, 0x01, priv); - pipc_write(1, 0x14, 0xf5, priv); - pipc_write(1, 0x15, 0x03, priv); - pipc_write(1, 0x18, 0x71, priv); - pipc_write(1, 0x19, 0x01, priv); - pipc_write(1, 0x1c, 0x75, priv); - pipc_write(1, 0x1d, 0x03, priv); - pipc_write(1, 0x20, 0x01, priv); - pipc_write(1, 0x21, 0xcc, priv); + pipc_write(1, 0x04, 1, 0x80, priv); + pipc_write(1, 0x09, 1, 0x85, priv); + pipc_write(1, 0x10, 1, 0xf1, priv); + pipc_write(1, 0x11, 1, 0x01, priv); + pipc_write(1, 0x14, 1, 0xf5, priv); + pipc_write(1, 0x15, 1, 0x03, priv); + pipc_write(1, 0x18, 1, 0x71, priv); + pipc_write(1, 0x19, 1, 0x01, priv); + pipc_write(1, 0x1c, 1, 0x75, priv); + pipc_write(1, 0x1d, 1, 0x03, priv); + pipc_write(1, 0x20, 1, 0x01, priv); + pipc_write(1, 0x21, 1, 0xcc, priv); if (dev->local <= VIA_PIPC_586B) - pipc_write(1, 0x40, 0x04, priv); + pipc_write(1, 0x40, 1, 0x04, priv); else - pipc_write(1, 0x40, 0x00, priv); + pipc_write(1, 0x40, 1, 0x00, priv); if (dev->local < VIA_PIPC_586B) - pipc_write(0, 0x44, 0x00, priv); + pipc_write(0, 0x44, 1, 0x00, priv); - pipc_write(0, 0x77, 0x00, priv); + pipc_write(0, 0x77, 1, 0x00, priv); sff_set_slot(dev->bm[0], dev->pci_slot); sff_set_slot(dev->bm[1], dev->pci_slot); diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index 3daeec85b0..467509fb6a 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -38,7 +38,7 @@ typedef struct vt82c505_t { } vt82c505_t; static void -vt82c505_write(int func, int addr, uint8_t val, void *priv) +vt82c505_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vt82c505_t *dev = (vt82c505_t *) priv; uint8_t irq; @@ -126,7 +126,7 @@ vt82c505_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -vt82c505_read(int func, int addr, void *priv) +vt82c505_read(int func, int addr, UNUSED(int len), void *priv) { const vt82c505_t *dev = (vt82c505_t *) priv; uint8_t ret = 0xff; @@ -147,7 +147,7 @@ vt82c505_out(uint16_t addr, uint8_t val, void *priv) if (addr == 0xa8) dev->index = val; else if ((addr == 0xa9) && (dev->index >= 0x80) && (dev->index <= 0x9f)) - vt82c505_write(0, dev->index, val, priv); + vt82c505_write(0, dev->index, 1, val, priv); } static uint8_t @@ -157,7 +157,7 @@ vt82c505_in(uint16_t addr, void *priv) uint8_t ret = 0xff; if ((addr == 0xa9) && (dev->index >= 0x80) && (dev->index <= 0x9f)) - ret = vt82c505_read(0, dev->index, priv); + ret = vt82c505_read(0, dev->index, 1, priv); return ret; } @@ -173,16 +173,16 @@ vt82c505_reset(void *priv) for (uint8_t i = 0x80; i <= 0x9f; i++) { switch (i) { case 0x81: - vt82c505_write(0, i, 0x01, priv); + vt82c505_write(0, i, 1, 0x01, priv); break; case 0x84: - vt82c505_write(0, i, 0x03, priv); + vt82c505_write(0, i, 1, 0x03, priv); break; case 0x93: - vt82c505_write(0, i, 0x40, priv); + vt82c505_write(0, i, 1, 0x40, priv); break; default: - vt82c505_write(0, i, 0x00, priv); + vt82c505_write(0, i, 1, 0x00, priv); break; } } diff --git a/src/chipset/vl82c59x.c b/src/chipset/vl82c59x.c index 69b6ebf1d6..30cc63065f 100644 --- a/src/chipset/vl82c59x.c +++ b/src/chipset/vl82c59x.c @@ -208,7 +208,7 @@ vl82c59x_set_pm_io(void *priv) } static void -vl82c59x_write(int func, int addr, uint8_t val, void *priv) +vl82c59x_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vl82c59x_t *dev = (vl82c59x_t *) priv; @@ -275,7 +275,7 @@ vl82c59x_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -vl82c59x_read(int func, int addr, void *priv) +vl82c59x_read(int func, int addr, UNUSED(int len), void *priv) { const vl82c59x_t *dev = (vl82c59x_t *) priv; uint8_t ret = 0xff; @@ -292,7 +292,7 @@ vl82c59x_read(int func, int addr, void *priv) } static void -vl82c59x_sb_write(int func, int addr, uint8_t val, void *priv) +vl82c59x_sb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vl82c59x_t *dev = (vl82c59x_t *) priv; uint8_t irq; @@ -380,7 +380,7 @@ vl82c59x_sb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -vl82c59x_sb_read(int func, int addr, void *priv) +vl82c59x_sb_read(int func, int addr, UNUSED(int len), void *priv) { const vl82c59x_t *dev = (vl82c59x_t *) priv; uint8_t ret = 0xff; diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index d9aeeffb65..0a323484a3 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -28,6 +28,7 @@ #include <86box/device.h> #include <86box/pci.h> #include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #define PCI_BRIDGE_DEC_21150 0x10110022 #define PCI_BRIDGE_DEC_21152 0x10110024 @@ -93,7 +94,7 @@ pci_bridge_get_bus_index(void *priv) } static void -pci_bridge_write(int func, int addr, uint8_t val, void *priv) +pci_bridge_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { pci_bridge_t *dev = (pci_bridge_t *) priv; @@ -391,7 +392,7 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -pci_bridge_read(int func, int addr, void *priv) +pci_bridge_read(int func, int addr, UNUSED(int len), void *priv) { const pci_bridge_t *dev = (pci_bridge_t *) priv; uint8_t ret; diff --git a/src/device/vfio.c b/src/device/vfio.c index 2217eb509f..776ded002a 100644 --- a/src/device/vfio.c +++ b/src/device/vfio.c @@ -246,12 +246,12 @@ vfio_log(const char *fmt, ...) #endif static uint8_t vfio_bar_gettype(vfio_device_t *dev, vfio_region_t *bar); -static uint8_t vfio_config_readb(int func, int addr, void *priv); -static uint16_t vfio_config_readw(int func, int addr, void *priv); -static uint32_t vfio_config_readl(int func, int addr, void *priv); -static void vfio_config_writeb(int func, int addr, uint8_t val, void *priv); -static void vfio_config_writew(int func, int addr, uint16_t val, void *priv); -static void vfio_config_writel(int func, int addr, uint32_t val, void *priv); +static uint8_t vfio_config_readb(int func, int addr, int len, void *priv); +static uint16_t vfio_config_readw(int func, int addr, int len, void *priv); +static uint32_t vfio_config_readl(int func, int addr, int len, void *priv); +static void vfio_config_writeb(int func, int addr, int len, uint8_t val, void *priv); +static void vfio_config_writew(int func, int addr, int len, uint16_t val, void *priv); +static void vfio_config_writel(int func, int addr, int len, uint32_t val, void *priv); static void vfio_irq_intx_setpin(vfio_device_t *dev); static void vfio_irq_msi_disable(vfio_device_t *dev); static void vfio_irq_msix_disable(vfio_device_t *dev); @@ -371,7 +371,7 @@ vfio_quirk_configmirror_readb(uint32_t addr, void *priv) vfio_mem_readb_fd(addr, bar); /* Read configuration register. */ - uint8_t ret = vfio_config_readb(0, addr - bar->quirks.configmirror.offset, dev); + uint8_t ret = vfio_config_readb(0, addr - bar->quirks.configmirror.offset, 1, dev); vfio_log_op("VFIO %s: Config mirror: Read %02X from index %02X\n", dev->name, ret, addr - bar->quirks.configmirror.offset); @@ -388,7 +388,7 @@ vfio_quirk_configmirror_readw(uint32_t addr, void *priv) vfio_mem_readw_fd(addr, bar); /* Read configuration register. */ - uint16_t ret = vfio_config_readw(0, addr - bar->quirks.configmirror.offset, dev); + uint16_t ret = vfio_config_readw(0, addr - bar->quirks.configmirror.offset, 2, dev); vfio_log_op("VFIO %s: Config mirror: Read %04X from index %02X\n", dev->name, ret, addr - bar->quirks.configmirror.offset); @@ -405,7 +405,7 @@ vfio_quirk_configmirror_readl(uint32_t addr, void *priv) vfio_mem_readl_fd(addr, bar); /* Read configuration register. */ - uint32_t ret = vfio_config_readl(0, addr - bar->quirks.configmirror.offset, dev); + uint32_t ret = vfio_config_readl(0, addr - bar->quirks.configmirror.offset, 4, dev); vfio_log_op("VFIO %s: Config mirror: Read %08X from index %02X\n", dev->name, ret, addr - bar->quirks.configmirror.offset); @@ -421,7 +421,7 @@ vfio_quirk_configmirror_writeb(uint32_t addr, uint8_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: Config mirror: Write %02X to index %02X\n", dev->name, val, addr - bar->quirks.configmirror.offset); - vfio_config_writeb(0, addr - bar->quirks.configmirror.offset, val, dev); + vfio_config_writeb(0, addr - bar->quirks.configmirror.offset, 1, val, dev); } static void @@ -433,7 +433,7 @@ vfio_quirk_configmirror_writew(uint32_t addr, uint16_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: Config mirror: Write %04X to index %02X\n", dev->name, val, addr - bar->quirks.configmirror.offset); - vfio_config_writew(0, addr - bar->quirks.configmirror.offset, val, dev); + vfio_config_writew(0, addr - bar->quirks.configmirror.offset, 2, val, dev); } static void @@ -445,7 +445,7 @@ vfio_quirk_configmirror_writel(uint32_t addr, uint32_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: Config mirror: Write %08X to index %02X\n", dev->name, val, addr - bar->quirks.configmirror.offset); - vfio_config_writel(0, addr - bar->quirks.configmirror.offset, val, dev); + vfio_config_writel(0, addr - bar->quirks.configmirror.offset, 4, val, dev); } static void @@ -541,11 +541,11 @@ vfio_quirk_configwindow_data_readb(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ uint32_t index = bar->quirks.configwindow.index; if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { - ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[0].start, dev); + ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[0].start, 1, dev); vfio_log_op("VFIO %s: Config window: Read %02X from primary index %08X\n", dev->name, ret, index); } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { - ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[1].start, dev); + ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[1].start, 1, dev); vfio_log_op("VFIO %s: Config window: Read %02X from secondary index %08X\n", dev->name, ret, index); } @@ -565,11 +565,11 @@ vfio_quirk_configwindow_data_readw(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ uint32_t index = bar->quirks.configwindow.index; if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { - ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[0].start, dev); + ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[0].start, 2, dev); vfio_log_op("VFIO %s: Config window: Read %04X from primary index %08X\n", dev->name, ret, index); } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { - ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[1].start, dev); + ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[1].start, 2, dev); vfio_log_op("VFIO %s: Config window: Read %04X from secondary index %08X\n", dev->name, ret, index); } @@ -589,11 +589,11 @@ vfio_quirk_configwindow_data_readl(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ uint32_t index = bar->quirks.configwindow.index; if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { - ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[0].start, dev); + ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[0].start, 4, dev); vfio_log_op("VFIO %s: Config window: Read %08X from primary index %08X\n", dev->name, ret, index); } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { - ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[1].start, dev); + ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[1].start, 4, dev); vfio_log_op("VFIO %s: Config window: Read %08X from secondary index %08X\n", dev->name, ret, index); } @@ -612,12 +612,12 @@ vfio_quirk_configwindow_data_writeb(uint16_t addr, uint8_t val, void *priv) if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { vfio_log_op("VFIO %s: Config window: Write %02X to primary index %08X\n", dev->name, val, index); - vfio_config_writeb(0, index - bar->quirks.configwindow.offset[0].start, val, dev); + vfio_config_writeb(0, index - bar->quirks.configwindow.offset[0].start, 1, val, dev); return; } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { vfio_log_op("VFIO %s: Config window: Write %02X to secondary index %08X\n", dev->name, val, index); - vfio_config_writeb(0, index - bar->quirks.configwindow.offset[1].start, val, dev); + vfio_config_writeb(0, index - bar->quirks.configwindow.offset[1].start, 1, val, dev); return; } @@ -636,12 +636,12 @@ vfio_quirk_configwindow_data_writew(uint16_t addr, uint16_t val, void *priv) if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { vfio_log_op("VFIO %s: Config window: Write %04X to primary index %08X\n", dev->name, val, index); - vfio_config_writew(0, index - bar->quirks.configwindow.offset[0].start, val, dev); + vfio_config_writew(0, index - bar->quirks.configwindow.offset[0].start, 2, val, dev); return; } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { vfio_log_op("VFIO %s: Config window: Write %04X to secondary index %08X\n", dev->name, val, index); - vfio_config_writew(0, index - bar->quirks.configwindow.offset[1].start, val, dev); + vfio_config_writew(0, index - bar->quirks.configwindow.offset[1].start, 2, val, dev); return; } @@ -660,12 +660,12 @@ vfio_quirk_configwindow_data_writel(uint16_t addr, uint32_t val, void *priv) if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { vfio_log_op("VFIO %s: Config window: Write %08X to primary index %08X\n", dev->name, val, index); - vfio_config_writel(0, index - bar->quirks.configwindow.offset[0].start, val, dev); + vfio_config_writel(0, index - bar->quirks.configwindow.offset[0].start, 4, val, dev); return; } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { vfio_log_op("VFIO %s: Config window: Write %08X to secondary index %08X\n", dev->name, val, index); - vfio_config_writel(0, index - bar->quirks.configwindow.offset[1].start, val, dev); + vfio_config_writel(0, index - bar->quirks.configwindow.offset[1].start, 4, val, dev); return; } @@ -1037,7 +1037,7 @@ vfio_quirk_nvidia3d0_data_readb(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ if ((prev_state == NVIDIA_3D0_READ) && (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000))) { - ret = vfio_config_readb(0, dev->quirks.nvidia3d0.index, dev); + ret = vfio_config_readb(0, dev->quirks.nvidia3d0.index, 1, dev); vfio_log_op("VFIO %s: NVIDIA 3D0: Read %02X from index %08X\n", dev->name, ret, dev->quirks.nvidia3d0.index); } @@ -1057,7 +1057,7 @@ vfio_quirk_nvidia3d0_data_readw(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ if ((prev_state == NVIDIA_3D0_READ) && (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000))) { - ret = vfio_config_readw(0, dev->quirks.nvidia3d0.index, dev); + ret = vfio_config_readw(0, dev->quirks.nvidia3d0.index, 2, dev); vfio_log_op("VFIO %s: NVIDIA 3D0: Read %04X from index %08X\n", dev->name, ret, dev->quirks.nvidia3d0.index); } @@ -1077,7 +1077,7 @@ vfio_quirk_nvidia3d0_data_readl(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ if ((prev_state == NVIDIA_3D0_READ) && (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000))) { - ret = vfio_config_readl(0, dev->quirks.nvidia3d0.index, dev); + ret = vfio_config_readl(0, dev->quirks.nvidia3d0.index, 4, dev); vfio_log_op("VFIO %s: NVIDIA 3D0: Read %08X from index %08X\n", dev->name, ret, dev->quirks.nvidia3d0.index); } @@ -1104,7 +1104,7 @@ vfio_quirk_nvidia3d0_data_writeb(uint16_t addr, uint8_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: NVIDIA 3D0: Write %02X to index %08X\n", dev->name, val, dev->quirks.nvidia3d0.index); - vfio_config_writeb(0, dev->quirks.nvidia3d0.index, val, dev); + vfio_config_writeb(0, dev->quirks.nvidia3d0.index, val, 1, dev); return; } } @@ -1131,7 +1131,7 @@ vfio_quirk_nvidia3d0_data_writew(uint16_t addr, uint16_t val, void *priv) if (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000)) { vfio_log_op("VFIO %s: NVIDIA 3D0: Write %04X to index %08X\n", dev->name, val, dev->quirks.nvidia3d0.index); - vfio_config_writew(0, dev->quirks.nvidia3d0.index, val, dev); + vfio_config_writew(0, dev->quirks.nvidia3d0.index, val, 2, dev); return; } } @@ -1159,7 +1159,7 @@ vfio_quirk_nvidia3d0_data_writel(uint16_t addr, uint32_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: NVIDIA 3D0: Write %08X to index %08X\n", dev->name, val, dev->quirks.nvidia3d0.index); - vfio_config_writel(0, dev->quirks.nvidia3d0.index, val, dev); + vfio_config_writel(0, dev->quirks.nvidia3d0.index, val, 4, dev); return; } } @@ -1198,7 +1198,7 @@ vfio_quirk_remap(vfio_device_t *dev, vfio_region_t *bar, uint8_t enable) /* BAR 2 configuration space mirror, and BAR 1/4 configuration space window. */ if (j && !i) { /* QEMU only enables the mirror here if BAR 2 is 64-bit capable. */ - if ((bar->bar_id == 2) && ((vfio_config_readb(0, 0x18, dev) & 0x07) == 0x04)) + if ((bar->bar_id == 2) && ((vfio_config_readb(0, 0x18, 1, dev) & 0x07) == 0x04)) vfio_quirk_configmirror(dev, bar, 0x4000, 0, enable); else if (bar->bar_id == 4) vfio_quirk_configwindow(dev, bar, 0x00, 4, 0x04, 4, 0x4000, 0x4000, enable); @@ -1479,7 +1479,7 @@ ceilpow2(uint32_t size) } static uint8_t -vfio_config_readb(int func, int addr, void *priv) +vfio_config_readb(int func, int addr, UNUSED(int len), void *priv) { vfio_device_t *dev = (vfio_device_t *) priv; if (func) @@ -1602,19 +1602,19 @@ vfio_config_readb(int func, int addr, void *priv) } static uint16_t -vfio_config_readw(int func, int addr, void *priv) +vfio_config_readw(int func, int addr, UNUSED(int len), void *priv) { - return vfio_config_readb(func, addr, priv) | (vfio_config_readb(func, addr + 1, priv) << 8); + return vfio_config_readb(func, addr, 2, priv) | (vfio_config_readb(func, addr + 1, 2, priv) << 8); } static uint32_t -vfio_config_readl(int func, int addr, void *priv) +vfio_config_readl(int func, int addr, UNUSED(int len), void *priv) { - return vfio_config_readb(func, addr, priv) | (vfio_config_readb(func, addr + 1, priv) << 8) | (vfio_config_readb(func, addr + 2, priv) << 16) | (vfio_config_readb(func, addr + 3, priv) << 24); + return vfio_config_readb(func, addr, 4, priv) | (vfio_config_readb(func, addr + 1, 4, priv) << 8) | (vfio_config_readb(func, addr + 2, 4, priv) << 16) | (vfio_config_readb(func, addr + 3, 4, priv) << 24); } static void -vfio_config_writeb(int func, int addr, uint8_t val, void *priv) +vfio_config_writeb(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vfio_device_t *dev = (vfio_device_t *) priv; if (func) @@ -1850,19 +1850,19 @@ vfio_config_writeb(int func, int addr, uint8_t val, void *priv) } static void -vfio_config_writew(int func, int addr, uint16_t val, void *priv) +vfio_config_writew(int func, int addr, UNUSED(int len), uint16_t val, void *priv) { - vfio_config_writeb(func, addr, val, priv); - vfio_config_writeb(func, addr | 1, val >> 8, priv); + vfio_config_writeb(func, addr, 2, val, priv); + vfio_config_writeb(func, addr | 1, 2, val >> 8, priv); } static void -vfio_config_writel(int func, int addr, uint32_t val, void *priv) +vfio_config_writel(int func, int addr, UNUSED(int len), uint32_t val, void *priv) { - vfio_config_writeb(func, addr, val, priv); - vfio_config_writeb(func, addr | 1, val >> 8, priv); - vfio_config_writeb(func, addr | 2, val >> 16, priv); - vfio_config_writeb(func, addr | 3, val >> 24, priv); + vfio_config_writeb(func, addr, 4, val, priv); + vfio_config_writeb(func, addr | 1, 4, val >> 8, priv); + vfio_config_writeb(func, addr | 2, 4, val >> 16, priv); + vfio_config_writeb(func, addr | 3, 4, val >> 24, priv); } static void @@ -2549,13 +2549,13 @@ vfio_dev_prereset(vfio_device_t *dev) /* Extra steps for devices with power management capability. */ if (dev->pm_cap) { /* Make sure the device is in D0 state. */ - uint8_t pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, dev), + uint8_t pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, 1, dev), state = pm_ctrl & 0x03; if (state) { pm_ctrl &= ~0x03; - vfio_config_writeb(0, dev->pm_cap + 4, pm_ctrl, dev); + vfio_config_writeb(0, dev->pm_cap + 4, pm_ctrl, 1, dev); - pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, dev); + pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, 1, dev); state = pm_ctrl & 0x03; if (state) vfio_log("VFIO %s: Device stuck in D%d state\n", dev->name, state); @@ -2566,10 +2566,10 @@ vfio_dev_prereset(vfio_device_t *dev) } /* Enable function-level reset if supported. */ - dev->can_flr_reset = (dev->pcie_cap && (vfio_config_readb(0, dev->pcie_cap + 7, dev) & 0x10)) || (dev->af_cap && (vfio_config_readb(0, dev->af_cap + 3, dev) & 0x02)); + dev->can_flr_reset = (dev->pcie_cap && (vfio_config_readb(0, dev->pcie_cap + 7, 1, dev) & 0x10)) || (dev->af_cap && (vfio_config_readb(0, dev->af_cap + 3, 1, dev) & 0x02)); /* Disable bus master, BARs, expansion ROM and VGA regions; also enable INTx. */ - vfio_config_writew(0, 0x04, vfio_config_readw(0, 0x04, dev) & ~0x0407, dev); + vfio_config_writew(0, 0x04, vfio_config_readw(0, 0x04, 2, dev) & ~0x0407, dev); } static void diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index ea2a195d94..44e488df4a 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -289,7 +290,7 @@ cmd640_vlb_readl(uint16_t addr, void *priv) } static void -cmd640_pci_write(int func, int addr, uint8_t val, void *priv) +cmd640_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { cmd640_t *dev = (cmd640_t *) priv; @@ -367,7 +368,7 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -cmd640_pci_read(int func, int addr, void *priv) +cmd640_pci_read(int func, int addr, UNUSED(int len), void *priv) { cmd640_t *dev = (cmd640_t *) priv; uint8_t ret = 0xff; diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 333cd5e30d..9cd50e8719 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -296,7 +297,7 @@ cmd646_bios_handler(cmd646_t *dev) } static void -cmd646_pci_write(int func, int addr, uint8_t val, void *priv) +cmd646_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { cmd646_t *dev = (cmd646_t *) priv; int reg50 = dev->regs[0x50]; @@ -481,7 +482,7 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -cmd646_pci_read(int func, int addr, void *priv) +cmd646_pci_read(int func, int addr, UNUSED(int len), void *priv) { cmd646_t *dev = (cmd646_t *) priv; uint8_t ret = 0xff; diff --git a/src/disk/hdc_ide_rz1000.c b/src/disk/hdc_ide_rz1000.c index 56568cc2c6..7559041b8b 100644 --- a/src/disk/hdc_ide_rz1000.c +++ b/src/disk/hdc_ide_rz1000.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -108,7 +109,7 @@ rz1000_ide_handlers(rz1000_t *dev) } static void -rz1000_pci_write(int func, int addr, uint8_t val, void *priv) +rz1000_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { rz1000_t *dev = (rz1000_t *) priv; @@ -138,7 +139,7 @@ rz1000_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -rz1000_pci_read(int func, int addr, void *priv) +rz1000_pci_read(int func, int addr, UNUSED(int len), void *priv) { rz1000_t *dev = (rz1000_t *) priv; uint8_t ret = 0xff; diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c index 25ee16d109..cb4d917788 100644 --- a/src/disk/hdc_ide_w83769f.c +++ b/src/disk/hdc_ide_w83769f.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -233,7 +234,7 @@ w83769f_vlb_readl(uint16_t addr, void *priv) } static void -w83769f_pci_write(int func, int addr, uint8_t val, void *priv) +w83769f_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { w83769f_t *dev = (w83769f_t *) priv; @@ -252,7 +253,7 @@ w83769f_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -w83769f_pci_read(int func, int addr, void *priv) +w83769f_pci_read(int func, int addr, UNUSED(int len), void *priv) { w83769f_t *dev = (w83769f_t *) priv; uint8_t ret = 0xff; diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index a721db005e..f5f5aee04f 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -266,12 +266,12 @@ extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number); extern void pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, int intd); /* Add a PCI card. */ -extern void pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), - void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot); +extern void pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot); /* Add an instance of the PCI bridge. */ -extern void pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, void *priv), - void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, +extern void pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot); /* Register the cards that have been added into slots. */ diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 3e2e7dd38a..decb23d028 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -799,7 +799,7 @@ nic_update_bios(nic_t *dev) } static uint8_t -nic_pci_read(UNUSED(int func), int addr, void *priv) +nic_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const nic_t *dev = (nic_t *) priv; uint8_t ret = 0x00; @@ -894,7 +894,7 @@ nic_pci_read(UNUSED(int func), int addr, void *priv) } static void -nic_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +nic_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { nic_t *dev = (nic_t *) priv; uint8_t valxor; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 2d9aa88bbf..e4cad2552e 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -2588,7 +2588,7 @@ pcnet_ioset(nic_t *dev, uint16_t addr, int len) } static void -pcnet_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +pcnet_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { nic_t *dev = (nic_t *) priv; uint8_t valxor; @@ -2671,7 +2671,7 @@ pcnet_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -pcnet_pci_read(UNUSED(int func), int addr, void *priv) +pcnet_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const nic_t *dev = (nic_t *) priv; diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 9cc52417fd..5c50f088cc 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3100,7 +3100,7 @@ rtl8139_timer(void *priv) } static uint8_t -rtl8139_pci_read(UNUSED(int func), int addr, void *priv) +rtl8139_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const RTL8139State *s = (RTL8139State *) priv; @@ -3157,7 +3157,7 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) } static void -rtl8139_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +rtl8139_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 3f1825a1e1..e95810cfa2 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1182,7 +1182,7 @@ tulip_srom_crc(uint8_t *eeprom) } static uint8_t -tulip_pci_read(UNUSED(int func), int addr, void *priv) +tulip_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const TULIPState *s = (TULIPState *) priv; uint8_t ret = 0; @@ -1301,7 +1301,7 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) } static void -tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +tulip_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { TULIPState *s = (TULIPState *) priv; diff --git a/src/pci.c b/src/pci.c index 16e8cdb4f0..9d08a9e08c 100644 --- a/src/pci.c +++ b/src/pci.c @@ -40,15 +40,15 @@ typedef struct pci_card_t { uint8_t irq_routing[PCI_INT_PINS_NUM]; void * priv; - void (*write)(int func, int addr, uint8_t val, void *priv); - uint8_t (*read)(int func, int addr, void *priv); + void (*write)(int func, int addr, int len, uint8_t val, void *priv); + uint8_t (*read)(int func, int addr, int len, void *priv); } pci_card_t; typedef struct pci_card_desc_t { uint8_t type; void * priv; - void (*write)(int func, int addr, uint8_t val, void *priv); - uint8_t (*read)(int func, int addr, void *priv); + void (*write)(int func, int addr, int len, uint8_t val, void *priv); + uint8_t (*read)(int func, int addr, int len, void *priv); uint8_t *slot; } pci_card_desc_t; @@ -91,6 +91,7 @@ static int pci_card; static int pci_bus; static int pci_key; static int pci_trc_reg = 0; +static int pci_access_len = 0; static uint32_t pci_enable = 0x00000000; static void pci_reset_regs(void); @@ -174,7 +175,7 @@ pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) return; if (pci_flags & FLAG_NO_IRQ_STEERING) - irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); + irq_line = pci_cards[slot].read(0, 0x3c, 1, pci_cards[slot].priv); else { irq_routing = pci_cards[slot].irq_routing[pci_int_index]; @@ -349,12 +350,12 @@ pci_reg_write(uint16_t port, uint8_t val) slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; if (slot != PCI_CARD_INVALID) { if (pci_cards[slot].write) - pci_cards[slot].write(pci_func, pci_index | (port & 0x03), val, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 0x03), pci_access_len, val, pci_cards[slot].priv); } - pci_log("PCI: [WB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %02X\n", + pci_log("PCI: [WB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X, length %I = %02X\n", (port >= 0xc000) ? 2 : 1, slot, (slot == PCI_CARD_INVALID) ? "non-existent" : (pci_cards[slot].write ? "used" : "unused"), - pci_card, pci_bus, pci_func, pci_index | (port & 0x03), val); + pci_card, pci_bus, pci_func, pci_index | (port & 0x03), pci_access_len, val); } static void @@ -364,6 +365,8 @@ pci_reset_regs(void) pci_enable = 0x00000000; pci_flags &= ~(FLAG_CONFIG_IO_ON | FLAG_CONFIG_M1_IO_ON); + + pci_access_len = 1; } void @@ -496,16 +499,24 @@ pci_writew(uint16_t port, uint16_t val, UNUSED(void *priv)) { if (port & 0x0001) { /* Non-aligned access, split into two byte accesses. */ + if (pci_access_len == 1) + pci_access_len = 2; pci_write(port, val & 0xff, priv); pci_write(port + 1, val >> 8, priv); + if (pci_access_len == 2) + pci_access_len = 1; } else { /* Aligned access, still split because we cheat. */ switch (port) { case 0xcfc: case 0xcfe: case 0xc000 ... 0xcffe: + if (pci_access_len == 1) + pci_access_len = 2; pci_write(port, val & 0xff, priv); pci_write(port + 1, val >> 8, priv); + if (pci_access_len == 2) + pci_access_len = 1; break; default: @@ -519,8 +530,10 @@ pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) { if (port & 0x0003) { /* Non-aligned access, split into two word accesses. */ + pci_access_len = 4; pci_writew(port, val & 0xffff, priv); pci_writew(port + 2, val >> 16, priv); + pci_access_len = 1; } else { /* Aligned access. */ switch (port) { @@ -545,8 +558,10 @@ pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) case 0xcfc: case 0xc000 ... 0xcffc: /* Still split because we cheat. */ + pci_access_len = 4; pci_writew(port, val & 0xffff, priv); pci_writew(port + 2, val >> 16, priv); + pci_access_len = 1; break; default: @@ -569,12 +584,12 @@ pci_reg_read(uint16_t port) slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; if (slot != PCI_CARD_INVALID) { if (pci_cards[slot].read) - ret = pci_cards[slot].read(pci_func, pci_index | (port & 0x03), pci_cards[slot].priv); + ret = pci_cards[slot].read(pci_func, pci_index | (port & 0x03), pci_access_len, pci_cards[slot].priv); } - pci_log("PCI: [RB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %02X\n", + pci_log("PCI: [RB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X, length %i = %02X\n", (port >= 0xc000) ? 2 : 1, slot, (slot == PCI_CARD_INVALID) ? "non-existent" : (pci_cards[slot].read ? "used" : "unused"), - pci_card, pci_bus, pci_func, pci_index | (port & 0x03), ret); + pci_card, pci_bus, pci_access_len, pci_index | (port & 0x03), pci_func, ret); return ret; } @@ -643,8 +658,12 @@ pci_readw(uint16_t port, UNUSED(void *priv)) case 0xcfc: case 0xcfe: case 0xc000 ... 0xcffe: + if (pci_access_len == 1) + pci_access_len = 2; ret = pci_read(port, priv); ret |= ((uint16_t) pci_read(port + 1, priv)) << 8; + if (pci_access_len == 2) + pci_access_len = 1; break; default: @@ -662,8 +681,10 @@ pci_readl(uint16_t port, UNUSED(void *priv)) if (port & 0x0003) { /* Non-aligned access, split into two word accesses. */ + pci_access_len = 4; ret = pci_readw(port, priv); ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + pci_access_len = 1; } else { /* Aligned access. */ switch (port) { @@ -682,8 +703,10 @@ pci_readl(uint16_t port, UNUSED(void *priv)) case 0xcfc: case 0xc000 ... 0xcffc: /* Still split because we cheat. */ + pci_access_len = 4; ret = pci_readw(port, priv); ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + pci_access_len = 1; break; } } @@ -781,8 +804,8 @@ pci_find_slot(uint8_t add_type, uint8_t ignore_slot) /* Add a PCI card. */ void -pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), - void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot) +pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot) { pci_card_desc_t *dev; @@ -853,7 +876,8 @@ pci_register_card(int pci_card) /* Add an instance of the PCI bridge. */ void -pci_add_bridge(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot) +pci_add_bridge(uint8_t add_type, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot) { pci_card_t *card; uint8_t bridge_slot = (add_type == PCI_ADD_NORMAL) ? last_normal_pci_card_id : pci_find_slot(add_type, 0xff); diff --git a/src/pci_dummy.c b/src/pci_dummy.c index bceb58c22d..e5395bed87 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -38,7 +38,7 @@ pci_dummy_interrupt(int set, pci_dummy_t *dev) } static uint8_t -pci_dummy_read(uint16_t port, void *priv) +pci_dummy_read(uint16_t port, UNUSED(int len), void *priv) { pci_dummy_t *dev = (pci_dummy_t *) priv; uint8_t ret = 0xff; @@ -90,7 +90,7 @@ pci_dummy_readl(uint16_t port, void *priv) } static void -pci_dummy_write(uint16_t port, UNUSED(uint8_t val), void *priv) +pci_dummy_write(uint16_t port, UNUSED(uint8_t val), UNUSED(int len), void *priv) { pci_dummy_t *dev = (pci_dummy_t *) priv; diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index daeb0a3e4c..754750b22d 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1117,7 +1117,7 @@ BuslogicBIOSUpdate(buslogic_data_t *bl) } static uint8_t -BuslogicPCIRead(UNUSED(int func), int addr, void *priv) +BuslogicPCIRead(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const x54x_t *dev = (x54x_t *) priv; #ifdef ENABLE_BUSLOGIC_LOG @@ -1203,7 +1203,7 @@ BuslogicPCIRead(UNUSED(int func), int addr, void *priv) } static void -BuslogicPCIWrite(UNUSED(int func), int addr, uint8_t val, void *priv) +BuslogicPCIWrite(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { x54x_t *dev = (x54x_t *) priv; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index bc3ecec0ba..eef94c916e 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2283,7 +2283,7 @@ uint8_t ncr53c8xx_pci_regs[256]; bar_t ncr53c8xx_pci_bar[4]; static uint8_t -ncr53c8xx_pci_read(UNUSED(int func), int addr, void *priv) +ncr53c8xx_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; @@ -2387,7 +2387,7 @@ ncr53c8xx_pci_read(UNUSED(int func), int addr, void *priv) } static void -ncr53c8xx_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ncr53c8xx_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; uint8_t valxor; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 11793f5a93..51aea3f46d 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1997,7 +1997,7 @@ esp_bios_disable(esp_t *dev) #define EE_ADAPT_OPTION_SCAM_SUPPORT 0x08 static uint8_t -esp_pci_read(UNUSED(int func), int addr, void *priv) +esp_pci_read(UNUSED(int func), int addr, int len, void *priv) { esp_t *dev = (esp_t *) priv; @@ -2009,12 +2009,15 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) if (!dev->has_bios || dev->local) return 0x22; else { - if (nmc93cxx_eeprom_read(dev->eeprom)) - return 0x22; - else { - dev->eeprom->dev.out = 1; - return 2; + uint8_t ret = 0x22; + + if (len == 1) { + /* First byte of address space is AND-ed with EEPROM DO line */ + if (!nmc93cxx_eeprom_read(dev->eeprom)) + ret &= 0x00; } + + return ret; } break; case 0x01: @@ -2084,7 +2087,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) } static void -esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +esp_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { esp_t *dev = (esp_t *) priv; uint8_t valxor; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 23c4863c76..9a4cb3c6ff 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -1905,7 +1905,7 @@ update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl) } static uint8_t -es1370_pci_read(int func, int addr, void *priv) +es1370_pci_read(int func, int addr, UNUSED(int len), void *priv) { const es137x_t *dev = (es137x_t *) priv; @@ -2001,7 +2001,7 @@ es1370_pci_read(int func, int addr, void *priv) } static uint8_t -es1371_pci_read(int func, int addr, void *priv) +es1371_pci_read(int func, int addr, UNUSED(int len), void *priv) { const es137x_t *dev = (es137x_t *) priv; @@ -2103,7 +2103,7 @@ es137x_io_set(es137x_t *dev, int set) } static void -es1370_pci_write(int func, int addr, uint8_t val, void *priv) +es1370_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { es137x_t *dev = (es137x_t *) priv; @@ -2154,7 +2154,7 @@ es1370_pci_write(int func, int addr, uint8_t val, void *priv) } static void -es1371_pci_write(int func, int addr, uint8_t val, void *priv) +es1371_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { es137x_t *dev = (es137x_t *) priv; diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index 9ee003689e..d4490ac239 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -966,7 +966,7 @@ cmi8x38_remap(cmi8x38_t *dev) } static uint8_t -cmi8x38_pci_read(int func, int addr, void *priv) +cmi8x38_pci_read(int func, int addr, UNUSED(int len), void *priv) { const cmi8x38_t *dev = (cmi8x38_t *) priv; uint8_t ret = 0xff; @@ -980,7 +980,7 @@ cmi8x38_pci_read(int func, int addr, void *priv) } static void -cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv) +cmi8x38_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { cmi8x38_t *dev = (cmi8x38_t *) priv; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index ceaf4224b8..8ce13f14d3 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -5129,7 +5129,7 @@ mach64_writel_be(uint32_t addr, uint32_t val, void *priv) } uint8_t -mach64_pci_read(UNUSED(int func), int addr, void *priv) +mach64_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const mach64_t *mach64 = (mach64_t *) priv; @@ -5214,7 +5214,7 @@ mach64_pci_read(UNUSED(int func), int addr, void *priv) } void -mach64_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +mach64_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { mach64_t *mach64 = (mach64_t *) priv; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index ccb1941460..fff9bce3ec 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -7092,7 +7092,7 @@ ati8514_pos_write(uint16_t port, uint8_t val, void *priv) } static uint8_t -mach32_pci_read(UNUSED(int func), int addr, void *priv) +mach32_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const mach_t *mach = (mach_t *) priv; uint8_t ret = 0x00; @@ -7171,7 +7171,7 @@ mach32_pci_read(UNUSED(int func), int addr, void *priv) } static void -mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +mach32_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; if ((addr >= 0x30) && (addr <= 0x33) && !mach->has_bios) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index 0a41bec2d5..d14e92ec13 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -39,6 +39,7 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> @@ -628,7 +629,7 @@ bochs_vbe_in(uint16_t addr, void *priv) } static uint8_t -bochs_vbe_pci_read(const int func, const int addr, void *priv) +bochs_vbe_pci_read(const int func, const int addr, UNUSED(const int len), void *priv) { const bochs_vbe_t *dev = (bochs_vbe_t *) priv; uint8_t ret = 0x00; @@ -711,7 +712,7 @@ bochs_vbe_disable_handlers(bochs_vbe_t *dev) } static void -bochs_vbe_pci_write(const int func, const int addr, const uint8_t val, void *priv) +bochs_vbe_pci_write(const int func, const int addr, UNUSED(const int len), const uint8_t val, void *priv) { bochs_vbe_t *dev = (bochs_vbe_t *) priv; diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index ef48207e15..2cd6c41620 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2141,7 +2141,7 @@ chips_69000_in(uint16_t addr, void *priv) } static uint8_t -chips_69000_pci_read(UNUSED(int func), int addr, void *priv) +chips_69000_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { chips_69000_t *chips = (chips_69000_t *) priv; uint8_t ret = 0x00; @@ -2215,7 +2215,7 @@ chips_69000_pci_read(UNUSED(int func), int addr, void *priv) } static void -chips_69000_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +chips_69000_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { chips_69000_t *chips = (chips_69000_t *) priv; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 4161e223e8..cec60332e2 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -3934,7 +3934,7 @@ gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *sv } static uint8_t -cl_pci_read(UNUSED(int func), int addr, void *priv) +cl_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const gd54xx_t *gd54xx = (gd54xx_t *) priv; const svga_t *svga = &gd54xx->svga; @@ -4046,7 +4046,7 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) } static void -cl_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +cl_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; const svga_t *svga = &gd54xx->svga; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 4abb9a7676..18d6b4575d 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2652,7 +2652,7 @@ et4000w32p_io_set(et4000w32p_t *et4000) } uint8_t -et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) +et4000w32p_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const et4000w32p_t *et4000 = (et4000w32p_t *) priv; @@ -2709,7 +2709,7 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) } void -et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +et4000w32p_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 07b0869f79..449b21866b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6337,7 +6337,7 @@ mystique_tvp3026_gpio_write(uint8_t cntl, uint8_t data, void *priv) } static uint8_t -mystique_pci_read(UNUSED(int func), int addr, void *priv) +mystique_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; @@ -6574,7 +6574,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) } static void -mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +mystique_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fc7499ff66..3965391cb9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -458,8 +458,8 @@ static void s3_accel_out_l(uint16_t port, uint32_t val, void *priv); static uint8_t s3_accel_in(uint16_t port, void *priv); static uint16_t s3_accel_in_w(uint16_t port, void *priv); static uint32_t s3_accel_in_l(uint16_t port, void *priv); -static uint8_t s3_pci_read(int func, int addr, void *priv); -static void s3_pci_write(int func, int addr, uint8_t val, void *priv); +static uint8_t s3_pci_read(int func, int addr, int len, void *priv); +static void s3_pci_write(int func, int addr, int len, uint8_t val, void *priv); #ifdef ENABLE_S3_LOG int s3_do_log = ENABLE_S3_LOG; @@ -2013,7 +2013,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) int addr_lo = addr & 1; if (svga->crtc[0x53] & 0x08) { if ((addr >= 0x08000) && (addr <= 0x0803f)) - s3_pci_write(0, addr & 0xff, val, s3); + s3_pci_write(0, addr & 0xff, 1, val, s3); } switch (addr & 0x1fffe) { @@ -6736,7 +6736,7 @@ s3_accel_read(uint32_t addr, void *priv) if (svga->crtc[0x53] & 0x08) { if ((addr >= 0x08000) && (addr <= 0x0803f)) - return s3_pci_read(0, addr & 0xff, s3); + return s3_pci_read(0, addr & 0xff, 1, s3); switch (addr & 0x1ffff) { case 0x83b0 ... 0x83df: return s3_in(addr & 0x3ff, s3); @@ -11001,7 +11001,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } static uint8_t -s3_pci_read(UNUSED(int func), int addr, void *priv) +s3_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const s3_t *s3 = (s3_t *) priv; const svga_t *svga = &s3->svga; @@ -11090,7 +11090,7 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) } static void -s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +s3_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index abeba064ec..b53dd5e8cc 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -5024,7 +5024,7 @@ s3_virge_overlay_draw(svga_t *svga, int displine) } static uint8_t -s3_virge_pci_read(UNUSED(int func), int addr, void *priv) +s3_virge_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const virge_t *virge = (virge_t *) priv; const svga_t *svga = &virge->svga; @@ -5189,7 +5189,7 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv) } static void -s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +s3_virge_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { virge_t *virge = (virge_t *) priv; svga_t *svga = &virge->svga; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 28c02363c7..2a76ee2a45 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -1096,7 +1096,7 @@ tgui_hwcursor_draw(svga_t *svga, int displine) } uint8_t -tgui_pci_read(UNUSED(int func), int addr, void *priv) +tgui_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const tgui_t *tgui = (tgui_t *) priv; @@ -1166,7 +1166,7 @@ tgui_pci_read(UNUSED(int func), int addr, void *priv) } void -tgui_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +tgui_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 72a57e66c7..78aba3cadd 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -1005,7 +1005,7 @@ voodoo_recalcmapping(voodoo_set_t *set) } uint8_t -voodoo_pci_read(int func, int addr, void *priv) +voodoo_pci_read(int func, int addr, UNUSED(int len), void *priv) { const voodoo_t *voodoo = (voodoo_t *) priv; @@ -1069,7 +1069,7 @@ voodoo_pci_read(int func, int addr, void *priv) } void -voodoo_pci_write(int func, int addr, uint8_t val, void *priv) +voodoo_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { voodoo_t *voodoo = (voodoo_t *) priv; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index f914c7e866..f6f0476ad0 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -3066,7 +3066,7 @@ banshee_vsync_callback(svga_t *svga) } static uint8_t -banshee_pci_read(int func, int addr, void *priv) +banshee_pci_read(int func, int addr, UNUSED(int len), void *priv) { const banshee_t *banshee = (banshee_t *) priv; #if 0 @@ -3276,7 +3276,7 @@ banshee_pci_read(int func, int addr, void *priv) } static void -banshee_pci_write(int func, int addr, uint8_t val, void *priv) +banshee_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { banshee_t *banshee = (banshee_t *) priv; #if 0 From 34c9b4c7d16126204a09ee063c79953bd525c672 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Jan 2026 16:25:21 +0100 Subject: [PATCH 34/58] NMC 93cXX EEPROM: Remove the left-over NULL check in nmc_93cxx_eeperom_data(). --- src/mem/nmc93cxx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mem/nmc93cxx.c b/src/mem/nmc93cxx.c index 17d97591ed..dada964547 100644 --- a/src/mem/nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -265,8 +265,6 @@ nmc93cxx_eeprom_close(void *priv) uint16_t * nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) { - if (UNLIKELY(eeprom == NULL)) - return NULL; /* Get EEPROM data array. */ return &eeprom->dev.data[0]; } From 9bd4114ecd29efe276b5e810d33a80fed9971070 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Jan 2026 17:55:20 +0100 Subject: [PATCH 35/58] Cirrus Logic: Reintroduce the thunks to SVGA reads/writes removed in build 5479, fixes E-Ten Chinese System. --- src/video/vid_cl54xx.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index cec60332e2..089b2ec7ff 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -2288,8 +2288,14 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) xga_write_test(addr, val, svga); + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + svga_write(addr, val, svga); + return; + } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; + svga_write_linear(addr, val, svga); } @@ -2312,6 +2318,11 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) xga_write_test(addr, val, svga); xga_write_test(addr + 1, val >> 8, svga); + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + svga_writew(addr, val, svga); + return; + } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2346,6 +2357,11 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) xga_write_test(addr + 2, val >> 16, svga); xga_write_test(addr + 3, val >> 24, svga); + if ((svga->seqregs[0x07] & 0x01) == 0) { + svga_writel(addr, val, svga); + return; + } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2898,6 +2914,9 @@ gd54xx_read(uint32_t addr, void *priv) svga_t *svga = (svga_t *) priv; gd54xx_t *gd54xx = (gd54xx_t *) svga->local; + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + return svga_read(addr, svga); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx, 0); @@ -2916,6 +2935,9 @@ gd54xx_readw(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) svga->local; uint16_t ret; + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + return svga_readw(addr, svga); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, svga); @@ -2938,6 +2960,9 @@ gd54xx_readl(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) svga->local; uint32_t ret; + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + return svga_readl(addr, svga); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, svga); From e747f868a5a12f1de312fb18d7d97863ca34ab4b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Jan 2026 00:46:42 +0100 Subject: [PATCH 36/58] Trident TGUI: Remove excess logging. --- src/video/vid_tgui9440.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 2a76ee2a45..f91fc3f961 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -784,7 +784,7 @@ tgui_recalctimings(svga_t *svga) else if (svga->gdcreg[0xf] & 0x40) svga->clock *= 3.0; - pclog("GDCREGF=%02x, miscout=%02x.\n", svga->gdcreg[0xf] & 0x48, svga->miscout & 0x0c); + // pclog("GDCREGF=%02x, miscout=%02x.\n", svga->gdcreg[0xf] & 0x48, svga->miscout & 0x0c); } else { //pclog("TGUI9400CXi: Clock double=%d.\n", (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8))); switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) { From c6d272fa9edfaea11a8a71e9c9f10077f335c0e1 Mon Sep 17 00:00:00 2001 From: BlueRain-debug Date: Thu, 22 Jan 2026 17:35:24 +0000 Subject: [PATCH 37/58] Translated using Weblate (Chinese (Simplified Han script)) Currently translated at 100.0% (1004 of 1004 strings) Translation: 86Box/86Box Translate-URL: https://weblate.86box.net/projects/86box/86box/zh_Hans/ --- src/qt/languages/zh-CN.po | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index a960d8b2d3..c922e207bd 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2026-01-18 19:18+0000\n" +"PO-Revision-Date: 2026-01-23 17:57+0000\n" "Last-Translator: BlueRain-debug \n" "Language-Team: Chinese (Simplified Han script) \n" @@ -2666,7 +2666,7 @@ msgid "&Unmute" msgstr "解除静音(&U)" msgid "Softfloat FPU" -msgstr "Softfloat FPU" +msgstr "软浮点FPU" msgid "High performance impact" msgstr "重大性能影响" From 570483a8287cc4b2e44bb464592b63a55b4f75bc Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Jan 2026 16:10:08 +0100 Subject: [PATCH 38/58] PCI: Make PCI configuration reads and writes length-aware and fix the DC390 PCI device ID AND'ing with EEPROM DO. --- src/chipset/ali1435.c | 4 +- src/chipset/ali1489.c | 4 +- src/chipset/ali1531.c | 18 ++--- src/chipset/ali1541.c | 20 ++--- src/chipset/ali1543.c | 130 ++++++++++++++++----------------- src/chipset/ali1621.c | 8 +- src/chipset/ims8848.c | 4 +- src/chipset/intel_420ex.c | 26 +++---- src/chipset/intel_4x0.c | 40 +++++----- src/chipset/intel_i450kx.c | 16 ++-- src/chipset/intel_piix.c | 90 +++++++++++------------ src/chipset/intel_sio.c | 22 +++--- src/chipset/opti822.c | 5 +- src/chipset/sis_5511.c | 8 +- src/chipset/sis_5571.c | 8 +- src/chipset/sis_5581.c | 8 +- src/chipset/sis_5591.c | 8 +- src/chipset/sis_5600.c | 8 +- src/chipset/sis_85c496.c | 54 +++++++------- src/chipset/sis_85c50x.c | 38 +++++----- src/chipset/stpc.c | 20 ++--- src/chipset/umc_8886.c | 5 +- src/chipset/umc_8890.c | 4 +- src/chipset/umc_hb4.c | 4 +- src/chipset/via_apollo.c | 15 ++-- src/chipset/via_pipc.c | 46 ++++++------ src/chipset/via_vt82c505.c | 16 ++-- src/chipset/vl82c59x.c | 8 +- src/device/pci_bridge.c | 5 +- src/device/vfio.c | 100 ++++++++++++------------- src/disk/hdc_ide_cmd640.c | 5 +- src/disk/hdc_ide_cmd646.c | 5 +- src/disk/hdc_ide_rz1000.c | 5 +- src/disk/hdc_ide_w83769f.c | 5 +- src/include/86box/pci.h | 8 +- src/network/net_ne2000.c | 4 +- src/network/net_pcnet.c | 4 +- src/network/net_rtl8139.c | 4 +- src/network/net_tulip.c | 4 +- src/pci.c | 52 +++++++++---- src/pci_dummy.c | 4 +- src/scsi/scsi_buslogic.c | 4 +- src/scsi/scsi_ncr53c8xx.c | 4 +- src/scsi/scsi_pcscsi.c | 17 +++-- src/sound/snd_audiopci.c | 8 +- src/sound/snd_cmi8x38.c | 4 +- src/video/vid_ati_mach64.c | 4 +- src/video/vid_ati_mach8.c | 4 +- src/video/vid_bochs_vbe.c | 5 +- src/video/vid_chips_69000.c | 4 +- src/video/vid_cl54xx.c | 4 +- src/video/vid_et4000w32.c | 4 +- src/video/vid_mga.c | 4 +- src/video/vid_s3.c | 12 +-- src/video/vid_s3_virge.c | 4 +- src/video/vid_tgui9440.c | 4 +- src/video/vid_voodoo.c | 4 +- src/video/vid_voodoo_banshee.c | 4 +- 58 files changed, 485 insertions(+), 451 deletions(-) diff --git a/src/chipset/ali1435.c b/src/chipset/ali1435.c index aebd10f32a..6619e033c1 100644 --- a/src/chipset/ali1435.c +++ b/src/chipset/ali1435.c @@ -98,7 +98,7 @@ ali1435_update_irqs(ali1435_t *dev, int set) } static void -ali1435_pci_write(int func, int addr, uint8_t val, void *priv) +ali1435_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1435_t *dev = (ali1435_t *) priv; int irq; @@ -163,7 +163,7 @@ ali1435_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali1435_pci_read(int func, int addr, void *priv) +ali1435_pci_read(int func, int addr, UNUSED(int len), void *priv) { const ali1435_t *dev = (ali1435_t *) priv; uint8_t ret; diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index 96ebd4a3d1..fdf0697ec9 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -411,7 +411,7 @@ ali1489_read(uint16_t addr, void *priv) } static void -ali1489_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1489_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1489_t *dev = (ali1489_t *) priv; @@ -434,7 +434,7 @@ ali1489_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1489_pci_read(UNUSED(int func), int addr, void *priv) +ali1489_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1489_t *dev = (ali1489_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/ali1531.c b/src/chipset/ali1531.c index 1603dbca4a..b57fe16063 100644 --- a/src/chipset/ali1531.c +++ b/src/chipset/ali1531.c @@ -132,7 +132,7 @@ ali1531_shadow_recalc(UNUSED(int cur_reg), ali1531_t *dev) } static void -ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1531_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1531_t *dev = (ali1531_t *) priv; @@ -298,7 +298,7 @@ ali1531_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1531_read(UNUSED(int func), int addr, void *priv) +ali1531_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1531_t *dev = (ali1531_t *) priv; uint8_t ret = 0xff; @@ -341,18 +341,18 @@ ali1531_reset(void *priv) dev->pci_conf[0x5a] = 0x20; dev->pci_conf[0x70] = 0x22; - ali1531_write(0, 0x42, 0x00, dev); - ali1531_write(0, 0x43, 0x00, dev); + ali1531_write(0, 0x42, 1, 0x00, dev); + ali1531_write(0, 0x43, 1, 0x00, dev); - ali1531_write(0, 0x47, 0x00, dev); - ali1531_write(0, 0x48, 0x00, dev); + ali1531_write(0, 0x47, 1, 0x00, dev); + ali1531_write(0, 0x48, 1, 0x00, dev); for (uint8_t i = 0; i < 4; i++) - ali1531_write(0, 0x4c + i, 0x00, dev); + ali1531_write(0, 0x4c + i, 1, 0x00, dev); for (uint8_t i = 0; i < 16; i += 2) { - ali1531_write(0, 0x60 + i, 0x08, dev); - ali1531_write(0, 0x61 + i, 0x40, dev); + ali1531_write(0, 0x60 + i, 1, 0x08, dev); + ali1531_write(0, 0x61 + i, 1, 0x40, dev); } } diff --git a/src/chipset/ali1541.c b/src/chipset/ali1541.c index 1506d880ab..02fd51c0ba 100644 --- a/src/chipset/ali1541.c +++ b/src/chipset/ali1541.c @@ -177,7 +177,7 @@ ali1541_mask_bar(ali1541_t *dev) } static void -ali1541_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1541_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1541_t *dev = (ali1541_t *) priv; @@ -562,7 +562,7 @@ ali1541_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1541_read(UNUSED(int func), int addr, void *priv) +ali1541_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1541_t *dev = (ali1541_t *) priv; uint8_t ret = 0xff; @@ -613,20 +613,20 @@ ali1541_reset(void *priv) dev->pci_conf[0xe0] = 0x01; cpu_cache_int_enabled = 1; - ali1541_write(0, 0x42, 0x00, dev); + ali1541_write(0, 0x42, 1, 0x00, dev); - ali1541_write(0, 0x54, 0x00, dev); - ali1541_write(0, 0x55, 0x00, dev); + ali1541_write(0, 0x54, 1, 0x00, dev); + ali1541_write(0, 0x55, 1, 0x00, dev); for (uint8_t i = 0; i < 4; i++) - ali1541_write(0, 0x56 + i, 0x00, dev); + ali1541_write(0, 0x56 + i, 1, 0x00, dev); - ali1541_write(0, 0x60, 0x07, dev); - ali1541_write(0, 0x61, 0x40, dev); + ali1541_write(0, 0x60, 1, 0x07, dev); + ali1541_write(0, 0x61, 1, 0x40, dev); for (uint8_t i = 0; i < 14; i += 2) { - ali1541_write(0, 0x62 + i, 0x00, dev); - ali1541_write(0, 0x63 + i, 0x00, dev); + ali1541_write(0, 0x62 + i, 1, 0x00, dev); + ali1541_write(0, 0x63 + i, 1, 0x00, dev); } } diff --git a/src/chipset/ali1543.c b/src/chipset/ali1543.c index 8ef8e6a204..3d5ddf603f 100644 --- a/src/chipset/ali1543.c +++ b/src/chipset/ali1543.c @@ -112,13 +112,13 @@ ali1533_ddma_handler(UNUSED(ali1543_t *dev)) static void ali5229_ide_handler(ali1543_t *dev); static void ali5229_ide_irq_handler(ali1543_t *dev); -static void ali5229_write(int func, int addr, uint8_t val, void *priv); +static void ali5229_write(int func, int addr, int len, uint8_t val, void *priv); -static void ali7101_write(int func, int addr, uint8_t val, void *priv); -static uint8_t ali7101_read(int func, int addr, void *priv); +static void ali7101_write(int func, int addr, int len, uint8_t val, void *priv); +static uint8_t ali7101_read(int func, int addr, int len, void *priv); static void -ali1533_write(int func, int addr, uint8_t val, void *priv) +ali1533_write(int func, int addr, int len, uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M1533: dev->pci_conf[%02x] = %02x\n", addr, val); @@ -453,7 +453,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) case 0x7c ... 0xff: if ((dev->type == 1) && !dev->pmu_dev_enable) { dev->pmu_dev_enable = 1; - ali7101_write(func, addr, val, priv); + ali7101_write(func, addr, len, val, priv); dev->pmu_dev_enable = 0; } break; @@ -464,7 +464,7 @@ ali1533_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali1533_read(int func, int addr, void *priv) +ali1533_read(int func, int addr, int len, void *priv) { ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -478,7 +478,7 @@ ali1533_read(int func, int addr, void *priv) ret = (ret & 0xbf) | (dev->ide_dev_enable ? 0x40 : 0x00); else if ((dev->type == 1) && ((addr >= 0x7c) && (addr <= 0xff)) && !dev->pmu_dev_enable) { dev->pmu_dev_enable = 1; - ret = ali7101_read(func, addr, priv); + ret = ali7101_read(func, addr, len, priv); dev->pmu_dev_enable = 0; } } @@ -690,23 +690,23 @@ ali5229_chip_reset(ali1543_t *dev) dev->ide_conf[0x4f] = 0x1a; } - ali5229_write(0, 0x04, 0x05, dev); - ali5229_write(0, 0x10, 0xf1, dev); - ali5229_write(0, 0x11, 0x01, dev); - ali5229_write(0, 0x14, 0xf5, dev); - ali5229_write(0, 0x15, 0x03, dev); - ali5229_write(0, 0x18, 0x71, dev); - ali5229_write(0, 0x19, 0x01, dev); - ali5229_write(0, 0x1a, 0x75, dev); - ali5229_write(0, 0x1b, 0x03, dev); - ali5229_write(0, 0x20, 0x01, dev); - ali5229_write(0, 0x21, 0xf0, dev); - ali5229_write(0, 0x4d, 0x00, dev); + ali5229_write(0, 0x04, 1, 0x05, dev); + ali5229_write(0, 0x10, 1, 0xf1, dev); + ali5229_write(0, 0x11, 1, 0x01, dev); + ali5229_write(0, 0x14, 1, 0xf5, dev); + ali5229_write(0, 0x15, 1, 0x03, dev); + ali5229_write(0, 0x18, 1, 0x71, dev); + ali5229_write(0, 0x19, 1, 0x01, dev); + ali5229_write(0, 0x1a, 1, 0x75, dev); + ali5229_write(0, 0x1b, 1, 0x03, dev); + ali5229_write(0, 0x20, 1, 0x01, dev); + ali5229_write(0, 0x21, 1, 0xf0, dev); + ali5229_write(0, 0x4d, 1, 0x00, dev); dev->ide_conf[0x09] = 0xfa; - ali5229_write(0, 0x09, 0xfa, dev); - ali5229_write(0, 0x52, 0x00, dev); + ali5229_write(0, 0x09, 1, 0xfa, dev); + ali5229_write(0, 0x52, 1, 0x00, dev); - ali5229_write(0, 0x50, 0x02, dev); + ali5229_write(0, 0x50, 1, 0x02, dev); sff_set_slot(dev->ide_controller[0], dev->ide_slot); sff_set_slot(dev->ide_controller[1], dev->ide_slot); @@ -716,7 +716,7 @@ ali5229_chip_reset(ali1543_t *dev) } static void -ali5229_write(int func, int addr, uint8_t val, void *priv) +ali5229_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M5229: [W] dev->ide_conf[%02x] = %02x\n", addr, val); @@ -885,7 +885,7 @@ ali5229_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali5229_read(int func, int addr, void *priv) +ali5229_read(int func, int addr, UNUSED(int len), void *priv) { const ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -908,7 +908,7 @@ ali5229_read(int func, int addr, void *priv) } static void -ali5237_write(int func, int addr, uint8_t val, void *priv) +ali5237_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M5237: dev->usb_conf[%02x] = %02x\n", addr, val); @@ -975,7 +975,7 @@ ali5237_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali5237_read(int func, int addr, void *priv) +ali5237_read(int func, int addr, UNUSED(int len), void *priv) { const ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -987,7 +987,7 @@ ali5237_read(int func, int addr, void *priv) } static void -ali7101_write(int func, int addr, uint8_t val, void *priv) +ali7101_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ali1543_t *dev = (ali1543_t *) priv; ali1543_log("M7101: [W] dev->pmu_conf[%02x] = %02x\n", addr, val); @@ -1408,7 +1408,7 @@ ali7101_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ali7101_read(int func, int addr, void *priv) +ali7101_read(int func, int addr, UNUSED(int len), void *priv) { ali1543_t *dev = (ali1543_t *) priv; uint8_t ret = 0xff; @@ -1516,11 +1516,11 @@ ali1543_reset(void *priv) dev->usb_conf[0x0b] = 0x0c; dev->usb_conf[0x3d] = 0x01; - ali5237_write(0, 0x04, 0x00, dev); - ali5237_write(0, 0x10, 0x00, dev); - ali5237_write(0, 0x11, 0x00, dev); - ali5237_write(0, 0x12, 0x00, dev); - ali5237_write(0, 0x13, 0x00, dev); + ali5237_write(0, 0x04, 1, 0x00, dev); + ali5237_write(0, 0x10, 1, 0x00, dev); + ali5237_write(0, 0x11, 1, 0x00, dev); + ali5237_write(0, 0x12, 1, 0x00, dev); + ali5237_write(0, 0x13, 1, 0x00, dev); /* M7101 */ memset(dev->pmu_conf, 0x00, sizeof(dev->pmu_conf)); @@ -1536,26 +1536,26 @@ ali1543_reset(void *priv) acpi_set_slot(dev->acpi, dev->pmu_slot); acpi_set_nvr(dev->acpi, dev->nvr); - ali7101_write(0, 0x04, 0x0f, dev); - ali7101_write(0, 0x10, 0x01, dev); - ali7101_write(0, 0x11, 0x00, dev); - ali7101_write(0, 0x12, 0x00, dev); - ali7101_write(0, 0x13, 0x00, dev); - ali7101_write(0, 0x14, 0x01, dev); - ali7101_write(0, 0x15, 0x00, dev); - ali7101_write(0, 0x16, 0x00, dev); - ali7101_write(0, 0x17, 0x00, dev); - ali7101_write(0, 0x40, 0x00, dev); - ali7101_write(0, 0x41, 0x00, dev); - ali7101_write(0, 0x42, 0x00, dev); - ali7101_write(0, 0x43, 0x00, dev); - ali7101_write(0, 0x77, 0x00, dev); - ali7101_write(0, 0xbd, 0x00, dev); - ali7101_write(0, 0xc0, 0x00, dev); - ali7101_write(0, 0xc1, 0x00, dev); - ali7101_write(0, 0xc2, 0x00, dev); - ali7101_write(0, 0xc3, 0x00, dev); - ali7101_write(0, 0xe0, 0x00, dev); + ali7101_write(0, 0x04, 1, 0x0f, dev); + ali7101_write(0, 0x10, 1, 0x01, dev); + ali7101_write(0, 0x11, 1, 0x00, dev); + ali7101_write(0, 0x12, 1, 0x00, dev); + ali7101_write(0, 0x13, 1, 0x00, dev); + ali7101_write(0, 0x14, 1, 0x01, dev); + ali7101_write(0, 0x15, 1, 0x00, dev); + ali7101_write(0, 0x16, 1, 0x00, dev); + ali7101_write(0, 0x17, 1, 0x00, dev); + ali7101_write(0, 0x40, 1, 0x00, dev); + ali7101_write(0, 0x41, 1, 0x00, dev); + ali7101_write(0, 0x42, 1, 0x00, dev); + ali7101_write(0, 0x43, 1, 0x00, dev); + ali7101_write(0, 0x77, 1, 0x00, dev); + ali7101_write(0, 0xbd, 1, 0x00, dev); + ali7101_write(0, 0xc0, 1, 0x00, dev); + ali7101_write(0, 0xc1, 1, 0x00, dev); + ali7101_write(0, 0xc2, 1, 0x00, dev); + ali7101_write(0, 0xc3, 1, 0x00, dev); + ali7101_write(0, 0xe0, 1, 0x00, dev); /* Do the bridge last due to device deactivations. */ /* M1533 */ @@ -1570,19 +1570,19 @@ ali1543_reset(void *priv) dev->pci_conf[0x0a] = 0x01; dev->pci_conf[0x0b] = 0x06; - ali1533_write(0, 0x41, 0x00, dev); /* Disables the keyboard and mouse IRQ latch. */ - ali1533_write(0, 0x48, 0x00, dev); /* Disables all IRQ's. */ - ali1533_write(0, 0x44, 0x00, dev); - ali1533_write(0, 0x4d, 0x00, dev); - ali1533_write(0, 0x53, 0x00, dev); - ali1533_write(0, 0x58, 0x00, dev); - ali1533_write(0, 0x5f, 0x00, dev); - ali1533_write(0, 0x72, 0x00, dev); - ali1533_write(0, 0x74, 0x00, dev); - ali1533_write(0, 0x75, 0x00, dev); - ali1533_write(0, 0x76, 0x00, dev); + ali1533_write(0, 0x41, 1, 0x00, dev); /* Disables the keyboard and mouse IRQ latch. */ + ali1533_write(0, 0x48, 1, 0x00, dev); /* Disables all IRQ's. */ + ali1533_write(0, 0x44, 1, 0x00, dev); + ali1533_write(0, 0x4d, 1, 0x00, dev); + ali1533_write(0, 0x53, 1, 0x00, dev); + ali1533_write(0, 0x58, 1, 0x00, dev); + ali1533_write(0, 0x5f, 1, 0x00, dev); + ali1533_write(0, 0x72, 1, 0x00, dev); + ali1533_write(0, 0x74, 1, 0x00, dev); + ali1533_write(0, 0x75, 1, 0x00, dev); + ali1533_write(0, 0x76, 1, 0x00, dev); if (dev->type == 1) - ali1533_write(0, 0x78, 0x00, dev); + ali1533_write(0, 0x78, 1, 0x00, dev); unmask_a20_in_smm = 1; } diff --git a/src/chipset/ali1621.c b/src/chipset/ali1621.c index 95602496c3..217c1b865a 100644 --- a/src/chipset/ali1621.c +++ b/src/chipset/ali1621.c @@ -255,7 +255,7 @@ ali1621_mask_bar(ali1621_t *dev) } static void -ali1621_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ali1621_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ali1621_t *dev = (ali1621_t *) priv; @@ -581,7 +581,7 @@ ali1621_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -ali1621_read(UNUSED(int func), int addr, void *priv) +ali1621_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const ali1621_t *dev = (ali1621_t *) priv; uint8_t ret = 0xff; @@ -647,10 +647,10 @@ ali1621_reset(void *priv) dev->pci_conf[0xf2] = dev->pci_conf[0xf6] = dev->pci_conf[0xfa] = dev->pci_conf[0xfe] = 0x21; dev->pci_conf[0xf3] = dev->pci_conf[0xf7] = dev->pci_conf[0xfb] = dev->pci_conf[0xff] = 0x43; - ali1621_write(0, 0x83, 0x08, dev); + ali1621_write(0, 0x83, 1, 0x08, dev); for (uint8_t i = 0; i < 4; i++) - ali1621_write(0, 0x84 + i, 0x00, dev); + ali1621_write(0, 0x84 + i, 1, 0x00, dev); } static void diff --git a/src/chipset/ims8848.c b/src/chipset/ims8848.c index 13fed304b6..16625f3a1e 100644 --- a/src/chipset/ims8848.c +++ b/src/chipset/ims8848.c @@ -292,7 +292,7 @@ ims8848_read(uint16_t addr, void *priv) } static void -ims8849_pci_write(int func, int addr, uint8_t val, void *priv) +ims8849_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { ims8848_t *dev = (ims8848_t *) priv; @@ -326,7 +326,7 @@ ims8849_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -ims8849_pci_read(int func, int addr, void *priv) +ims8849_pci_read(int func, UNUSED(int len), int addr, void *priv) { const ims8848_t *dev = (ims8848_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/intel_420ex.c b/src/chipset/intel_420ex.c index daa55c72c9..67e2ae0699 100644 --- a/src/chipset/intel_420ex.c +++ b/src/chipset/intel_420ex.c @@ -183,7 +183,7 @@ i420ex_drb_recalc(i420ex_t *dev) static void -i420ex_write(int func, int addr, uint8_t val, void *priv) +i420ex_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i420ex_t *dev = (i420ex_t *) priv; @@ -397,7 +397,7 @@ i420ex_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -i420ex_read(int func, int addr, void *priv) +i420ex_read(int func, int addr, UNUSED(int len), void *priv) { const i420ex_t *dev = (i420ex_t *) priv; uint8_t ret; @@ -472,31 +472,31 @@ i420ex_reset(void *priv) { i420ex_t *dev = (i420ex_t *) priv; - i420ex_write(0, 0x48, 0x00, priv); + i420ex_write(0, 0x48, 1, 0x00, priv); /* Disable the PIC mouse latch. */ - i420ex_write(0, 0x4e, 0x03, priv); + i420ex_write(0, 0x4e, 1, 0x03, priv); for (uint8_t i = 0; i < 7; i++) - i420ex_write(0, 0x59 + i, 0x00, priv); + i420ex_write(0, 0x59 + i, 1, 0x00, priv); for (uint8_t i = 0; i <= 4; i++) dev->regs[0x60 + i] = 0x01; dev->regs[0x70] &= 0xef; /* Forcibly unlock the SMRAM register. */ dev->smram_locked = 0; - i420ex_write(0, 0x70, 0x00, priv); + i420ex_write(0, 0x70, 1, 0x00, priv); mem_set_mem_state(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); mem_set_mem_state_smm(0x000a0000, 0x00060000, MEM_READ_EXTANY | MEM_WRITE_EXTANY); - i420ex_write(0, 0xa0, 0x08, priv); - i420ex_write(0, 0xa2, 0x00, priv); - i420ex_write(0, 0xa4, 0x00, priv); - i420ex_write(0, 0xa5, 0x00, priv); - i420ex_write(0, 0xa6, 0x00, priv); - i420ex_write(0, 0xa7, 0x00, priv); - i420ex_write(0, 0xa8, 0x0f, priv); + i420ex_write(0, 0xa0, 1, 0x08, priv); + i420ex_write(0, 0xa2, 1, 0x00, priv); + i420ex_write(0, 0xa4, 1, 0x00, priv); + i420ex_write(0, 0xa5, 1, 0x00, priv); + i420ex_write(0, 0xa6, 1, 0x00, priv); + i420ex_write(0, 0xa7, 1, 0x00, priv); + i420ex_write(0, 0xa8, 1, 0x0f, priv); } static void diff --git a/src/chipset/intel_4x0.c b/src/chipset/intel_4x0.c index 18f4ee66a9..48627e39b5 100644 --- a/src/chipset/intel_4x0.c +++ b/src/chipset/intel_4x0.c @@ -243,7 +243,7 @@ pm2_cntrl_write(UNUSED(uint16_t addr), uint8_t val, void *priv) } static void -i4x0_write(int func, int addr, uint8_t val, void *priv) +i4x0_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i4x0_t *dev = (i4x0_t *) priv; uint8_t *regs = (uint8_t *) dev->regs; @@ -1535,7 +1535,7 @@ i4x0_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -i4x0_read(int func, int addr, void *priv) +i4x0_read(int func, int addr, UNUSED(int len), void *priv) { i4x0_t *dev = (i4x0_t *) priv; uint8_t ret = 0xff; @@ -1563,12 +1563,12 @@ i4x0_reset(void *priv) memset(dev->regs_locked, 0x00, 256 * sizeof(uint8_t)); if (dev->type >= INTEL_430FX) - i4x0_write(0, 0x59, 0x00, priv); + i4x0_write(0, 0x59, 1, 0x00, priv); else - i4x0_write(0, 0x59, 0x0f, priv); + i4x0_write(0, 0x59, 1, 0x0f, priv); for (uint8_t i = 0; i < 6; i++) - i4x0_write(0, 0x5a + i, 0x00, priv); + i4x0_write(0, 0x5a + i, 1, 0x00, priv); for (uint8_t i = 0; i <= dev->max_drb; i++) dev->regs[0x60 + i] = dev->drb_default; @@ -1582,18 +1582,18 @@ i4x0_reset(void *priv) if (dev->type >= INTEL_430FX) { dev->regs[0x72] &= 0xef; /* Forcibly unlock the SMRAM register. */ - i4x0_write(0, 0x72, 0x02, priv); + i4x0_write(0, 0x72, 1, 0x02, priv); } else if (dev->type >= INTEL_430LX) { dev->regs[0x72] &= 0xf7; /* Forcibly unlock the SMRAM register. */ - i4x0_write(0, 0x72, 0x00, priv); + i4x0_write(0, 0x72, 1, 0x00, priv); } else { dev->regs[0x57] &= 0xef; /* Forcibly unlock the SMRAM register. */ - i4x0_write(0, 0x57, 0x02, priv); + i4x0_write(0, 0x57, 1, 0x02, priv); } if ((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) { i4x0_write(0, (dev->type >= INTEL_440BX) ? 0x73 : 0x71, - (dev->type >= INTEL_440BX) ? 0x38 : 0x00, priv); + 1, (dev->type >= INTEL_440BX) ? 0x38 : 0x00, priv); } } @@ -1932,24 +1932,24 @@ i4x0_init(const device_t *info) else if (dev->type >= INTEL_440LX) cpu_set_agp_speed(cpu_busspeed); - i4x0_write(regs[0x59], 0x59, 0x00, dev); - i4x0_write(regs[0x5a], 0x5a, 0x00, dev); - i4x0_write(regs[0x5b], 0x5b, 0x00, dev); - i4x0_write(regs[0x5c], 0x5c, 0x00, dev); - i4x0_write(regs[0x5d], 0x5d, 0x00, dev); - i4x0_write(regs[0x5e], 0x5e, 0x00, dev); - i4x0_write(regs[0x5f], 0x5f, 0x00, dev); + i4x0_write(regs[0x59], 0x59, 1, 0x00, dev); + i4x0_write(regs[0x5a], 0x5a, 1, 0x00, dev); + i4x0_write(regs[0x5b], 0x5b, 1, 0x00, dev); + i4x0_write(regs[0x5c], 0x5c, 1, 0x00, dev); + i4x0_write(regs[0x5d], 0x5d, 1, 0x00, dev); + i4x0_write(regs[0x5e], 0x5e, 1, 0x00, dev); + i4x0_write(regs[0x5f], 0x5f, 1, 0x00, dev); if (dev->type >= INTEL_430FX) - i4x0_write(0, 0x72, 0x02, dev); + i4x0_write(0, 0x72, 1, 0x02, dev); else if (dev->type >= INTEL_430LX) - i4x0_write(0, 0x72, 0x00, dev); + i4x0_write(0, 0x72, 1, 0x00, dev); else - i4x0_write(0, 0x57, 0x02, dev); + i4x0_write(0, 0x57, 1, 0x02, dev); if ((dev->type == INTEL_430TX) || (dev->type >= INTEL_440BX)) { i4x0_write(0, (dev->type >= INTEL_440BX) ? 0x73 : 0x71, - (dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev); + 1, (dev->type >= INTEL_440BX) ? 0x38 : 0x00, dev); } pci_add_card(PCI_ADD_NORTHBRIDGE, i4x0_read, i4x0_write, dev, &dev->pci_slot); diff --git a/src/chipset/intel_i450kx.c b/src/chipset/intel_i450kx.c index 34cc6a62f7..cb793179a5 100644 --- a/src/chipset/intel_i450kx.c +++ b/src/chipset/intel_i450kx.c @@ -126,7 +126,7 @@ i450kx_vid_buf_recalc(i450kx_t *dev, int bus) } static void -pb_write(int func, int addr, uint8_t val, void *priv) +pb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; @@ -371,7 +371,7 @@ pb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -pb_read(int func, int addr, void *priv) +pb_read(int func, int addr, UNUSED(int len), void *priv) { const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; @@ -400,7 +400,7 @@ mc_fill_drbs(i450kx_t *dev) } static void -mc_write(int func, int addr, uint8_t val, void *priv) +mc_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { i450kx_t *dev = (i450kx_t *) priv; @@ -601,7 +601,7 @@ mc_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -mc_read(int func, int addr, void *priv) +mc_read(int func, int addr, UNUSED(int len), void *priv) { const i450kx_t *dev = (i450kx_t *) priv; uint8_t ret = 0xff; @@ -707,9 +707,9 @@ i450kx_reset(void *priv) #endif i450kx_smram_recalc(dev, 1); i450kx_vid_buf_recalc(dev, 1); - pb_write(0, 0x59, 0x30, dev); + pb_write(0, 0x59, 1, 0x30, dev); for (i = 0x5a; i <= 0x5f; i++) - pb_write(0, i, 0x33, dev); + pb_write(0, i, 1, 0x33, dev); /* Defaults MC */ dev->mc_pci_conf[0x00] = 0x86; @@ -779,9 +779,9 @@ i450kx_reset(void *priv) i450kx_smram_recalc(dev, 0); i450kx_vid_buf_recalc(dev, 0); - mc_write(0, 0x59, 0x03, dev); + mc_write(0, 0x59, 1, 0x03, dev); for (i = 0x5a; i <= 0x5f; i++) - mc_write(0, i, 0x00, dev); + mc_write(0, i, 1, 0x00, dev); for (i = 0x60; i <= 0x6f; i++) dev->mc_pci_conf[i] = 0x01; } diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index 9d4d88687d..9f78148699 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -464,7 +464,7 @@ piix_trap_update(void *priv) } static void -piix_write(int func, int addr, uint8_t val, void *priv) +piix_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { piix_t *dev = (piix_t *) priv; uint8_t *fregs; @@ -1192,7 +1192,7 @@ piix_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -piix_read(int func, int addr, void *priv) +piix_read(int func, int addr, UNUSED(int len), void *priv) { piix_t *dev = (piix_t *) priv; uint8_t ret = 0xff; @@ -1447,68 +1447,68 @@ piix_reset(void *priv) const piix_t *dev = (piix_t *) priv; if (dev->type > 3) { - piix_write(3, 0x04, 0x00, priv); - piix_write(3, 0x5b, 0x00, priv); + piix_write(3, 0x04, 1, 0x00, priv); + piix_write(3, 0x5b, 1, 0x00, priv); } else { - piix_write(0, 0xa0, 0x08, priv); - piix_write(0, 0xa2, 0x00, priv); - piix_write(0, 0xa4, 0x00, priv); - piix_write(0, 0xa5, 0x00, priv); - piix_write(0, 0xa6, 0x00, priv); - piix_write(0, 0xa7, 0x00, priv); - piix_write(0, 0xa8, 0x0f, priv); + piix_write(0, 0xa0, 1, 0x08, priv); + piix_write(0, 0xa2, 1, 0x00, priv); + piix_write(0, 0xa4, 1, 0x00, priv); + piix_write(0, 0xa5, 1, 0x00, priv); + piix_write(0, 0xa6, 1, 0x00, priv); + piix_write(0, 0xa7, 1, 0x00, priv); + piix_write(0, 0xa8, 1, 0x0f, priv); } /* Disable the PIC mouse latch. */ - piix_write(0, 0x4e, 0x03, priv); + piix_write(0, 0x4e, 1, 0x03, priv); if (dev->type == 5) - piix_write(0, 0xe1, 0x40, priv); - piix_write(1, 0x04, 0x00, priv); + piix_write(0, 0xe1, 1, 0x40, priv); + piix_write(1, 0x04, 1, 0x00, priv); if (dev->type == 5) { - piix_write(1, 0x09, 0x8a, priv); - piix_write(1, 0x10, 0xf1, priv); - piix_write(1, 0x11, 0x01, priv); - piix_write(1, 0x14, 0xf5, priv); - piix_write(1, 0x15, 0x03, priv); - piix_write(1, 0x18, 0x71, priv); - piix_write(1, 0x19, 0x01, priv); - piix_write(1, 0x1c, 0x75, priv); - piix_write(1, 0x1d, 0x03, priv); + piix_write(1, 0x09, 1, 0x8a, priv); + piix_write(1, 0x10, 1, 0xf1, priv); + piix_write(1, 0x11, 1, 0x01, priv); + piix_write(1, 0x14, 1, 0xf5, priv); + piix_write(1, 0x15, 1, 0x03, priv); + piix_write(1, 0x18, 1, 0x71, priv); + piix_write(1, 0x19, 1, 0x01, priv); + piix_write(1, 0x1c, 1, 0x75, priv); + piix_write(1, 0x1d, 1, 0x03, priv); } else - piix_write(1, 0x09, 0x80, priv); - piix_write(1, 0x20, 0x01, priv); - piix_write(1, 0x21, 0x00, priv); - piix_write(1, 0x41, 0x00, priv); - piix_write(1, 0x43, 0x00, priv); + piix_write(1, 0x09, 1, 0x80, priv); + piix_write(1, 0x20, 1, 0x01, priv); + piix_write(1, 0x21, 1, 0x00, priv); + piix_write(1, 0x41, 1, 0x00, priv); + piix_write(1, 0x43, 1, 0x00, priv); ide_pri_disable(); ide_sec_disable(); if (dev->type >= 3) { - piix_write(2, 0x04, 0x00, priv); + piix_write(2, 0x04, 1, 0x00, priv); if (dev->type == 5) { - piix_write(2, 0x10, 0x00, priv); - piix_write(2, 0x11, 0x00, priv); - piix_write(2, 0x12, 0x00, priv); - piix_write(2, 0x13, 0x00, priv); + piix_write(2, 0x10, 1, 0x00, priv); + piix_write(2, 0x11, 1, 0x00, priv); + piix_write(2, 0x12, 1, 0x00, priv); + piix_write(2, 0x13, 1, 0x00, priv); } else { - piix_write(2, 0x20, 0x01, priv); - piix_write(2, 0x21, 0x00, priv); - piix_write(2, 0x22, 0x00, priv); - piix_write(2, 0x23, 0x00, priv); + piix_write(2, 0x20, 1, 0x01, priv); + piix_write(2, 0x21, 1, 0x00, priv); + piix_write(2, 0x22, 1, 0x00, priv); + piix_write(2, 0x23, 1, 0x00, priv); } } if (dev->type >= 4) { - piix_write(0, 0xb0, is_pentium ? 0x00 : 0x04, priv); - piix_write(3, 0x40, 0x01, priv); - piix_write(3, 0x41, 0x00, priv); - piix_write(3, 0x5b, 0x00, priv); - piix_write(3, 0x80, 0x00, priv); - piix_write(3, 0x90, 0x01, priv); - piix_write(3, 0x91, 0x00, priv); - piix_write(3, 0xd2, 0x00, priv); + piix_write(0, 0xb0, 1, is_pentium ? 0x00 : 0x04, priv); + piix_write(3, 0x40, 1, 0x01, priv); + piix_write(3, 0x41, 1, 0x00, priv); + piix_write(3, 0x5b, 1, 0x00, priv); + piix_write(3, 0x80, 1, 0x00, priv); + piix_write(3, 0x90, 1, 0x01, priv); + piix_write(3, 0x91, 1, 0x00, priv); + piix_write(3, 0xd2, 1, 0x00, priv); } sff_set_irq_mode(dev->bm[0], IRQ_MODE_LEGACY); diff --git a/src/chipset/intel_sio.c b/src/chipset/intel_sio.c index 739785acb7..c28fa5471e 100644 --- a/src/chipset/intel_sio.c +++ b/src/chipset/intel_sio.c @@ -135,7 +135,7 @@ sio_timer_readw(uint16_t addr, void *priv) } static void -sio_write(int func, int addr, uint8_t val, void *priv) +sio_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { sio_t *dev = (sio_t *) priv; uint8_t old; @@ -324,7 +324,7 @@ sio_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sio_read(int func, int addr, void *priv) +sio_read(int func, int addr, UNUSED(int len), void *priv) { const sio_t *dev = (sio_t *) priv; uint8_t ret; @@ -473,20 +473,20 @@ sio_reset(void *priv) const sio_t *dev = (sio_t *) priv; /* Disable the PIC mouse latch. */ - sio_write(0, 0x4d, 0x40, priv); + sio_write(0, 0x4d, 1, 0x40, priv); - sio_write(0, 0x57, 0x04, priv); + sio_write(0, 0x57, 1, 0x04, priv); dma_set_params(1, 0xffffffff); if (dev->id == 0x03) { - sio_write(0, 0xa0, 0x08, priv); - sio_write(0, 0xa2, 0x00, priv); - sio_write(0, 0xa4, 0x00, priv); - sio_write(0, 0xa5, 0x00, priv); - sio_write(0, 0xa6, 0x00, priv); - sio_write(0, 0xa7, 0x00, priv); - sio_write(0, 0xa8, 0x0f, priv); + sio_write(0, 0xa0, 1, 0x08, priv); + sio_write(0, 0xa2, 1, 0x00, priv); + sio_write(0, 0xa4, 1, 0x00, priv); + sio_write(0, 0xa5, 1, 0x00, priv); + sio_write(0, 0xa6, 1, 0x00, priv); + sio_write(0, 0xa7, 1, 0x00, priv); + sio_write(0, 0xa8, 1, 0x0f, priv); } } diff --git a/src/chipset/opti822.c b/src/chipset/opti822.c index 2f416a1c27..2029a6b40c 100644 --- a/src/chipset/opti822.c +++ b/src/chipset/opti822.c @@ -48,7 +48,6 @@ typedef struct opti822_t { uint8_t pci_regs[256]; } opti822_t; -// #define ENABLE_OPTI822_LOG 1 #ifdef ENABLE_OPTI822_LOG int opti822_do_log = ENABLE_OPTI822_LOG; @@ -131,7 +130,7 @@ opti822_update_irqs(opti822_t *dev, int set) } static void -opti822_pci_write(int func, int addr, uint8_t val, void *priv) +opti822_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { opti822_t *dev = (opti822_t *) priv; int irq; @@ -336,7 +335,7 @@ opti822_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -opti822_pci_read(int func, int addr, void *priv) +opti822_pci_read(int func, int addr, UNUSED(int len), void *priv) { const opti822_t *dev = (opti822_t *) priv; uint8_t ret; diff --git a/src/chipset/sis_5511.c b/src/chipset/sis_5511.c index 38fcfe717a..c22f798afc 100644 --- a/src/chipset/sis_5511.c +++ b/src/chipset/sis_5511.c @@ -76,7 +76,7 @@ typedef struct sis_5511_t { } sis_5511_t; static void -sis_5511_write(int func, int addr, uint8_t val, void *priv) +sis_5511_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; @@ -87,7 +87,7 @@ sis_5511_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5511_read(int func, int addr, void *priv) +sis_5511_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; @@ -101,7 +101,7 @@ sis_5511_read(int func, int addr, void *priv) } static void -sis_5513_write(int func, int addr, uint8_t val, void *priv) +sis_5513_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; @@ -114,7 +114,7 @@ sis_5513_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5513_read(int func, int addr, void *priv) +sis_5513_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5511_t *dev = (sis_5511_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5571.c b/src/chipset/sis_5571.c index 02e86a98a8..824f1f3386 100644 --- a/src/chipset/sis_5571.c +++ b/src/chipset/sis_5571.c @@ -75,7 +75,7 @@ typedef struct sis_5571_t { } sis_5571_t; static void -sis_5571_write(int func, int addr, uint8_t val, void *priv) +sis_5571_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; @@ -86,7 +86,7 @@ sis_5571_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5571_read(int func, int addr, void *priv) +sis_5571_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; @@ -100,7 +100,7 @@ sis_5571_read(int func, int addr, void *priv) } static void -sis_5572_write(int func, int addr, uint8_t val, void *priv) +sis_5572_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; @@ -120,7 +120,7 @@ sis_5572_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5572_read(int func, int addr, void *priv) +sis_5572_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5571_t *dev = (sis_5571_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5581.c b/src/chipset/sis_5581.c index 525fe65980..ea54a407b2 100644 --- a/src/chipset/sis_5581.c +++ b/src/chipset/sis_5581.c @@ -75,7 +75,7 @@ typedef struct sis_5581_t { } sis_5581_t; static void -sis_5581_write(int func, int addr, uint8_t val, void *priv) +sis_5581_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; @@ -86,7 +86,7 @@ sis_5581_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5581_read(int func, int addr, void *priv) +sis_5581_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; uint8_t ret = 0xff; @@ -100,7 +100,7 @@ sis_5581_read(int func, int addr, void *priv) } static void -sis_5582_write(int func, int addr, uint8_t val, void *priv) +sis_5582_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; @@ -120,7 +120,7 @@ sis_5582_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5582_read(int func, int addr, void *priv) +sis_5582_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5581_t *dev = (sis_5581_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5591.c b/src/chipset/sis_5591.c index d814e0f749..48cbe97654 100644 --- a/src/chipset/sis_5591.c +++ b/src/chipset/sis_5591.c @@ -76,7 +76,7 @@ typedef struct sis_5591_t { } sis_5591_t; static void -sis_5591_write(int func, int addr, uint8_t val, void *priv) +sis_5591_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; @@ -89,7 +89,7 @@ sis_5591_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5591_read(int func, int addr, void *priv) +sis_5591_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; uint8_t ret = 0xff; @@ -105,7 +105,7 @@ sis_5591_read(int func, int addr, void *priv) } static void -sis_5595_write(int func, int addr, uint8_t val, void *priv) +sis_5595_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; @@ -125,7 +125,7 @@ sis_5595_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5595_read(int func, int addr, void *priv) +sis_5595_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5591_t *dev = (sis_5591_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_5600.c b/src/chipset/sis_5600.c index 564243c68c..2610ea88fa 100644 --- a/src/chipset/sis_5600.c +++ b/src/chipset/sis_5600.c @@ -76,7 +76,7 @@ typedef struct sis_5600_t { } sis_5600_t; static void -sis_5600_write(int func, int addr, uint8_t val, void *priv) +sis_5600_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; @@ -89,7 +89,7 @@ sis_5600_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5600_read(int func, int addr, void *priv) +sis_5600_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; uint8_t ret = 0xff; @@ -105,7 +105,7 @@ sis_5600_read(int func, int addr, void *priv) } static void -sis_5595_write(int func, int addr, uint8_t val, void *priv) +sis_5595_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; @@ -125,7 +125,7 @@ sis_5595_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_5595_read(int func, int addr, void *priv) +sis_5595_read(int func, int addr, UNUSED(int len), void *priv) { const sis_5600_t *dev = (sis_5600_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/sis_85c496.c b/src/chipset/sis_85c496.c index f2c1941d49..a04f016331 100644 --- a/src/chipset/sis_85c496.c +++ b/src/chipset/sis_85c496.c @@ -216,7 +216,7 @@ sis_85c496_drb_recalc(sis_85c496_t *dev) /* 00 - 3F = PCI Configuration, 40 - 7F = 85C496, 80 - FF = 85C497 */ static void -sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +sis_85c49x_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; uint8_t old; @@ -507,7 +507,7 @@ sis_85c49x_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -sis_85c49x_pci_read(UNUSED(int func), int addr, void *priv) +sis_85c49x_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const sis_85c496_t *dev = (sis_85c496_t *) priv; uint8_t ret = dev->pci_conf[addr]; @@ -577,35 +577,35 @@ sis_85c496_reset(void *priv) { sis_85c496_t *dev = (sis_85c496_t *) priv; - sis_85c49x_pci_write(0, 0x44, 0x00, dev); - sis_85c49x_pci_write(0, 0x45, 0x00, dev); - sis_85c49x_pci_write(0, 0x58, 0x00, dev); - sis_85c49x_pci_write(0, 0x59, 0x00, dev); - sis_85c49x_pci_write(0, 0x5a, 0x00, dev); - // sis_85c49x_pci_write(0, 0x5a, 0x06, dev); + sis_85c49x_pci_write(0, 0x44, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x45, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x58, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x59, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x5a, 1, 0x00, dev); + // sis_85c49x_pci_write(0, 0x5a, 1, 0x06, dev); for (uint8_t i = 0; i < 8; i++) dev->pci_conf[0x48 + i] = 0x02; - sis_85c49x_pci_write(0, 0x80, 0x00, dev); - sis_85c49x_pci_write(0, 0x81, 0x00, dev); - sis_85c49x_pci_write(0, 0x9e, 0x00, dev); - sis_85c49x_pci_write(0, 0x8d, 0x00, dev); - sis_85c49x_pci_write(0, 0xa0, 0xff, dev); - sis_85c49x_pci_write(0, 0xa1, 0xff, dev); - sis_85c49x_pci_write(0, 0xc0, 0x00, dev); - sis_85c49x_pci_write(0, 0xc1, 0x00, dev); - sis_85c49x_pci_write(0, 0xc2, 0x00, dev); - sis_85c49x_pci_write(0, 0xc3, 0x00, dev); - sis_85c49x_pci_write(0, 0xc8, 0x00, dev); - sis_85c49x_pci_write(0, 0xc9, 0x00, dev); - sis_85c49x_pci_write(0, 0xca, 0x00, dev); - sis_85c49x_pci_write(0, 0xcb, 0x00, dev); - - sis_85c49x_pci_write(0, 0xd0, 0x79, dev); - sis_85c49x_pci_write(0, 0xd1, 0xff, dev); - sis_85c49x_pci_write(0, 0xd0, 0x78, dev); - sis_85c49x_pci_write(0, 0xd4, 0x00, dev); + sis_85c49x_pci_write(0, 0x80, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x81, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x9e, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0x8d, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xa0, 1, 0xff, dev); + sis_85c49x_pci_write(0, 0xa1, 1, 0xff, dev); + sis_85c49x_pci_write(0, 0xc0, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc1, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc2, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc3, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc8, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xc9, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xca, 1, 0x00, dev); + sis_85c49x_pci_write(0, 0xcb, 1, 0x00, dev); + + sis_85c49x_pci_write(0, 0xd0, 1, 0x79, dev); + sis_85c49x_pci_write(0, 0xd1, 1, 0xff, dev); + sis_85c49x_pci_write(0, 0xd0, 1, 0x78, dev); + sis_85c49x_pci_write(0, 0xd4, 1, 0x00, dev); dev->pci_conf[0x67] = 0x00; dev->pci_conf[0xc6] = 0x00; diff --git a/src/chipset/sis_85c50x.c b/src/chipset/sis_85c50x.c index e932ff6ca6..5eb3b518d9 100644 --- a/src/chipset/sis_85c50x.c +++ b/src/chipset/sis_85c50x.c @@ -199,7 +199,7 @@ sis_85c50x_smm_recalc(sis_85c50x_t *dev) } static void -sis_85c50x_write(int func, int addr, uint8_t val, void *priv) +sis_85c50x_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { sis_85c50x_t *dev = (sis_85c50x_t *) priv; @@ -311,7 +311,7 @@ sis_85c50x_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_85c50x_read(int func, int addr, void *priv) +sis_85c50x_read(int func, int addr, UNUSED(int len), void *priv) { const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; @@ -344,7 +344,7 @@ sis_85c50x_ide_recalc(sis_85c50x_t *dev) } static void -sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) +sis_85c50x_sb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { sis_85c50x_t *dev = (sis_85c50x_t *) priv; @@ -393,7 +393,7 @@ sis_85c50x_sb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -sis_85c50x_sb_read(int func, int addr, void *priv) +sis_85c50x_sb_read(int func, int addr, UNUSED(int len), void *priv) { const sis_85c50x_t *dev = (sis_85c50x_t *) priv; uint8_t ret = 0xff; @@ -553,17 +553,17 @@ sis_85c50x_reset(void *priv) dev->pci_conf[0x0a] = 0x00; dev->pci_conf[0x0b] = 0x06; - sis_85c50x_write(0, 0x51, 0x00, dev); - sis_85c50x_write(0, 0x53, 0x00, dev); - sis_85c50x_write(0, 0x54, 0x00, dev); - sis_85c50x_write(0, 0x55, 0x00, dev); - sis_85c50x_write(0, 0x56, 0x00, dev); - sis_85c50x_write(0, 0x5b, 0x00, dev); - sis_85c50x_write(0, 0x60, 0x00, dev); - sis_85c50x_write(0, 0x64, 0x00, dev); - sis_85c50x_write(0, 0x65, 0x00, dev); - sis_85c50x_write(0, 0x68, 0x00, dev); - sis_85c50x_write(0, 0x69, 0xff, dev); + sis_85c50x_write(0, 0x51, 1, 0x00, dev); + sis_85c50x_write(0, 0x53, 1, 0x00, dev); + sis_85c50x_write(0, 0x54, 1, 0x00, dev); + sis_85c50x_write(0, 0x55, 1, 0x00, dev); + sis_85c50x_write(0, 0x56, 1, 0x00, dev); + sis_85c50x_write(0, 0x5b, 1, 0x00, dev); + sis_85c50x_write(0, 0x60, 1, 0x00, dev); + sis_85c50x_write(0, 0x64, 1, 0x00, dev); + sis_85c50x_write(0, 0x65, 1, 0x00, dev); + sis_85c50x_write(0, 0x68, 1, 0x00, dev); + sis_85c50x_write(0, 0x69, 1, 0xff, dev); if (dev->type & 1) { for (uint8_t i = 0; i < 8; i++) @@ -586,10 +586,10 @@ sis_85c50x_reset(void *priv) dev->pci_conf_sb[0x0b] = 0x06; if (dev->type & 2) dev->pci_conf_sb[0x0e] = 0x80; - sis_85c50x_sb_write(0, 0x41, 0x80, dev); - sis_85c50x_sb_write(0, 0x42, 0x80, dev); - sis_85c50x_sb_write(0, 0x43, 0x80, dev); - sis_85c50x_sb_write(0, 0x44, 0x80, dev); + sis_85c50x_sb_write(0, 0x41, 1, 0x80, dev); + sis_85c50x_sb_write(0, 0x42, 1, 0x80, dev); + sis_85c50x_sb_write(0, 0x43, 1, 0x80, dev); + sis_85c50x_sb_write(0, 0x44, 1, 0x80, dev); if (dev->type & 2) { /* IDE (SiS 5503) */ diff --git a/src/chipset/stpc.c b/src/chipset/stpc.c index 56eca8268d..e78a68c20b 100644 --- a/src/chipset/stpc.c +++ b/src/chipset/stpc.c @@ -213,7 +213,7 @@ stpc_localbus_read(uint16_t addr, void *priv) } static void -stpc_nb_write(int func, int addr, uint8_t val, void *priv) +stpc_nb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; @@ -260,7 +260,7 @@ stpc_nb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_nb_read(int func, int addr, void *priv) +stpc_nb_read(int func, int addr, UNUSED(int len), void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; @@ -337,7 +337,7 @@ stpc_ide_bm_handlers(stpc_t *dev) } static void -stpc_ide_write(int func, int addr, uint8_t val, void *priv) +stpc_ide_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; @@ -445,7 +445,7 @@ stpc_ide_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_ide_read(int func, int addr, void *priv) +stpc_ide_read(int func, int addr, UNUSED(int len), void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; @@ -466,12 +466,12 @@ stpc_ide_read(int func, int addr, void *priv) } static void -stpc_isab_write(int func, int addr, uint8_t val, void *priv) +stpc_isab_write(int func, int addr, int len, uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; if ((func == 1) && (dev->local != STPC_ATLAS)) { - stpc_ide_write(0, addr, val, priv); + stpc_ide_write(0, addr, len, val, priv); return; } @@ -507,13 +507,13 @@ stpc_isab_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_isab_read(int func, int addr, void *priv) +stpc_isab_read(int func, int addr, int len, void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; if ((func == 1) && (dev->local != STPC_ATLAS)) - ret = stpc_ide_read(0, addr, priv); + ret = stpc_ide_read(0, addr, len, priv); else if (func > 0) ret = 0xff; else @@ -524,7 +524,7 @@ stpc_isab_read(int func, int addr, void *priv) } static void -stpc_usb_write(int func, int addr, uint8_t val, void *priv) +stpc_usb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { stpc_t *dev = (stpc_t *) priv; @@ -571,7 +571,7 @@ stpc_usb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -stpc_usb_read(int func, int addr, void *priv) +stpc_usb_read(int func, int addr, UNUSED(int len), void *priv) { const stpc_t *dev = (stpc_t *) priv; uint8_t ret; diff --git a/src/chipset/umc_8886.c b/src/chipset/umc_8886.c index 3725394c3d..7350f50584 100644 --- a/src/chipset/umc_8886.c +++ b/src/chipset/umc_8886.c @@ -84,6 +84,7 @@ #include <86box/machine.h> #include <86box/pic.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/port_92.h> #include <86box/chipset.h> @@ -187,7 +188,7 @@ umc_8886_irq_recalc(umc_8886_t *dev) } static void -umc_8886_write(int func, int addr, uint8_t val, void *priv) +umc_8886_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { umc_8886_t *dev = (umc_8886_t *) priv; @@ -293,7 +294,7 @@ umc_8886_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -umc_8886_read(int func, int addr, void *priv) +umc_8886_read(int func, int addr, UNUSED(int len), void *priv) { const umc_8886_t *dev = (umc_8886_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/umc_8890.c b/src/chipset/umc_8890.c index cb69ce6a8d..1be55de887 100644 --- a/src/chipset/umc_8890.c +++ b/src/chipset/umc_8890.c @@ -119,7 +119,7 @@ um8890_smram(umc_8890_t *dev) } static void -um8890_write(int func, int addr, uint8_t val, void *priv) +um8890_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { umc_8890_t *dev = (umc_8890_t *)priv; @@ -158,7 +158,7 @@ um8890_write(int func, int addr, uint8_t val, void *priv) static uint8_t -um8890_read(int func, int addr, void *priv) +um8890_read(int func, int addr, UNUSED(int len), void *priv) { umc_8890_t *dev = (umc_8890_t *)priv; uint8_t ret = 0xff; diff --git a/src/chipset/umc_hb4.c b/src/chipset/umc_hb4.c index 55901b32ea..ae62da1664 100644 --- a/src/chipset/umc_hb4.c +++ b/src/chipset/umc_hb4.c @@ -275,7 +275,7 @@ hb4_smram(hb4_t *dev) } static void -hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) +hb4_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { hb4_t *dev = (hb4_t *) priv; @@ -336,7 +336,7 @@ hb4_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -hb4_read(int func, int addr, void *priv) +hb4_read(int func, int addr, UNUSED(int len), void *priv) { const hb4_t *dev = (hb4_t *) priv; uint8_t ret = 0xff; diff --git a/src/chipset/via_apollo.c b/src/chipset/via_apollo.c index 3236bbbbe8..b4646ba04f 100644 --- a/src/chipset/via_apollo.c +++ b/src/chipset/via_apollo.c @@ -29,6 +29,7 @@ #include <86box/device.h> #include <86box/pci.h> #include <86box/chipset.h> +#include <86box/plat_unused.h> #include <86box/spd.h> #include <86box/agpgart.h> @@ -225,7 +226,7 @@ via_apollo_setup(via_apollo_t *dev) } static void -via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) +via_apollo_host_bridge_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { via_apollo_t *dev = (via_apollo_t *) priv; if (func) @@ -684,7 +685,7 @@ via_apollo_host_bridge_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -via_apollo_read(int func, int addr, void *priv) +via_apollo_read(int func, int addr, UNUSED(int len), void *priv) { const via_apollo_t *dev = (via_apollo_t *) priv; uint8_t ret = 0xff; @@ -701,11 +702,11 @@ via_apollo_read(int func, int addr, void *priv) } static void -via_apollo_write(int func, int addr, uint8_t val, void *priv) +via_apollo_write(int func, int addr, int len, uint8_t val, void *priv) { switch (func) { case 0: - via_apollo_host_bridge_write(func, addr, val, priv); + via_apollo_host_bridge_write(func, addr, len, val, priv); break; default: break; @@ -715,9 +716,9 @@ via_apollo_write(int func, int addr, uint8_t val, void *priv) static void via_apollo_reset(void *priv) { - via_apollo_write(0, 0x61, 0x00, priv); - via_apollo_write(0, 0x62, 0x00, priv); - via_apollo_write(0, 0x63, 0x00, priv); + via_apollo_write(0, 0x61, 1, 0x00, priv); + via_apollo_write(0, 0x62, 1, 0x00, priv); + via_apollo_write(0, 0x63, 1, 0x00, priv); } static void * diff --git a/src/chipset/via_pipc.c b/src/chipset/via_pipc.c index a476b9b990..a5883791ec 100644 --- a/src/chipset/via_pipc.c +++ b/src/chipset/via_pipc.c @@ -170,8 +170,8 @@ pipc_log(const char *fmt, ...) static void pipc_sgd_handlers(pipc_t *dev, uint8_t modem); static void pipc_codec_handlers(pipc_t *dev, uint8_t modem); static void pipc_sb_handlers(pipc_t *dev, uint8_t modem); -static uint8_t pipc_read(int func, int addr, void *priv); -static void pipc_write(int func, int addr, uint8_t val, void *priv); +static uint8_t pipc_read(int func, int addr, int len, void *priv); +static void pipc_write(int func, int addr, int len, uint8_t val, void *priv); static void pipc_io_trap_pact(UNUSED(int size), UNUSED(uint16_t addr), UNUSED(uint8_t write), UNUSED(uint8_t val), void *priv) @@ -930,7 +930,7 @@ pipc_sb_get_buffer(int32_t *buffer, int len, void *priv) } static uint8_t -pipc_read(int func, int addr, void *priv) +pipc_read(int func, int addr, UNUSED(int len), void *priv) { pipc_t *dev = (pipc_t *) priv; uint8_t ret = 0xff; @@ -1026,7 +1026,7 @@ pipc_ddma_update(pipc_t *dev, int addr) } static void -pipc_write(int func, int addr, uint8_t val, void *priv) +pipc_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { pipc_t *dev = (pipc_t *) priv; int c; @@ -1661,34 +1661,34 @@ pipc_reset(void *priv) pipc_t *dev = (pipc_t *) priv; uint8_t pm_func = dev->usb[1] ? 4 : 3; - pipc_write(pm_func, 0x41, 0x00, priv); - pipc_write(pm_func, 0x48, 0x01, priv); - pipc_write(pm_func, 0x49, 0x00, priv); + pipc_write(pm_func, 0x41, 1, 0x00, priv); + pipc_write(pm_func, 0x48, 1, 0x01, priv); + pipc_write(pm_func, 0x49, 1, 0x00, priv); dev->power_regs[0x42] = ((dev->local >> 16) == VIA_PIPC_586) ? 0x00 : 0x50; acpi_set_irq_line(dev->acpi, 0x00); - pipc_write(1, 0x04, 0x80, priv); - pipc_write(1, 0x09, 0x85, priv); - pipc_write(1, 0x10, 0xf1, priv); - pipc_write(1, 0x11, 0x01, priv); - pipc_write(1, 0x14, 0xf5, priv); - pipc_write(1, 0x15, 0x03, priv); - pipc_write(1, 0x18, 0x71, priv); - pipc_write(1, 0x19, 0x01, priv); - pipc_write(1, 0x1c, 0x75, priv); - pipc_write(1, 0x1d, 0x03, priv); - pipc_write(1, 0x20, 0x01, priv); - pipc_write(1, 0x21, 0xcc, priv); + pipc_write(1, 0x04, 1, 0x80, priv); + pipc_write(1, 0x09, 1, 0x85, priv); + pipc_write(1, 0x10, 1, 0xf1, priv); + pipc_write(1, 0x11, 1, 0x01, priv); + pipc_write(1, 0x14, 1, 0xf5, priv); + pipc_write(1, 0x15, 1, 0x03, priv); + pipc_write(1, 0x18, 1, 0x71, priv); + pipc_write(1, 0x19, 1, 0x01, priv); + pipc_write(1, 0x1c, 1, 0x75, priv); + pipc_write(1, 0x1d, 1, 0x03, priv); + pipc_write(1, 0x20, 1, 0x01, priv); + pipc_write(1, 0x21, 1, 0xcc, priv); if (dev->local <= VIA_PIPC_586B) - pipc_write(1, 0x40, 0x04, priv); + pipc_write(1, 0x40, 1, 0x04, priv); else - pipc_write(1, 0x40, 0x00, priv); + pipc_write(1, 0x40, 1, 0x00, priv); if (dev->local < VIA_PIPC_586B) - pipc_write(0, 0x44, 0x00, priv); + pipc_write(0, 0x44, 1, 0x00, priv); - pipc_write(0, 0x77, 0x00, priv); + pipc_write(0, 0x77, 1, 0x00, priv); sff_set_slot(dev->bm[0], dev->pci_slot); sff_set_slot(dev->bm[1], dev->pci_slot); diff --git a/src/chipset/via_vt82c505.c b/src/chipset/via_vt82c505.c index 3daeec85b0..467509fb6a 100644 --- a/src/chipset/via_vt82c505.c +++ b/src/chipset/via_vt82c505.c @@ -38,7 +38,7 @@ typedef struct vt82c505_t { } vt82c505_t; static void -vt82c505_write(int func, int addr, uint8_t val, void *priv) +vt82c505_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vt82c505_t *dev = (vt82c505_t *) priv; uint8_t irq; @@ -126,7 +126,7 @@ vt82c505_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -vt82c505_read(int func, int addr, void *priv) +vt82c505_read(int func, int addr, UNUSED(int len), void *priv) { const vt82c505_t *dev = (vt82c505_t *) priv; uint8_t ret = 0xff; @@ -147,7 +147,7 @@ vt82c505_out(uint16_t addr, uint8_t val, void *priv) if (addr == 0xa8) dev->index = val; else if ((addr == 0xa9) && (dev->index >= 0x80) && (dev->index <= 0x9f)) - vt82c505_write(0, dev->index, val, priv); + vt82c505_write(0, dev->index, 1, val, priv); } static uint8_t @@ -157,7 +157,7 @@ vt82c505_in(uint16_t addr, void *priv) uint8_t ret = 0xff; if ((addr == 0xa9) && (dev->index >= 0x80) && (dev->index <= 0x9f)) - ret = vt82c505_read(0, dev->index, priv); + ret = vt82c505_read(0, dev->index, 1, priv); return ret; } @@ -173,16 +173,16 @@ vt82c505_reset(void *priv) for (uint8_t i = 0x80; i <= 0x9f; i++) { switch (i) { case 0x81: - vt82c505_write(0, i, 0x01, priv); + vt82c505_write(0, i, 1, 0x01, priv); break; case 0x84: - vt82c505_write(0, i, 0x03, priv); + vt82c505_write(0, i, 1, 0x03, priv); break; case 0x93: - vt82c505_write(0, i, 0x40, priv); + vt82c505_write(0, i, 1, 0x40, priv); break; default: - vt82c505_write(0, i, 0x00, priv); + vt82c505_write(0, i, 1, 0x00, priv); break; } } diff --git a/src/chipset/vl82c59x.c b/src/chipset/vl82c59x.c index 69b6ebf1d6..30cc63065f 100644 --- a/src/chipset/vl82c59x.c +++ b/src/chipset/vl82c59x.c @@ -208,7 +208,7 @@ vl82c59x_set_pm_io(void *priv) } static void -vl82c59x_write(int func, int addr, uint8_t val, void *priv) +vl82c59x_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vl82c59x_t *dev = (vl82c59x_t *) priv; @@ -275,7 +275,7 @@ vl82c59x_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -vl82c59x_read(int func, int addr, void *priv) +vl82c59x_read(int func, int addr, UNUSED(int len), void *priv) { const vl82c59x_t *dev = (vl82c59x_t *) priv; uint8_t ret = 0xff; @@ -292,7 +292,7 @@ vl82c59x_read(int func, int addr, void *priv) } static void -vl82c59x_sb_write(int func, int addr, uint8_t val, void *priv) +vl82c59x_sb_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vl82c59x_t *dev = (vl82c59x_t *) priv; uint8_t irq; @@ -380,7 +380,7 @@ vl82c59x_sb_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -vl82c59x_sb_read(int func, int addr, void *priv) +vl82c59x_sb_read(int func, int addr, UNUSED(int len), void *priv) { const vl82c59x_t *dev = (vl82c59x_t *) priv; uint8_t ret = 0xff; diff --git a/src/device/pci_bridge.c b/src/device/pci_bridge.c index d9aeeffb65..0a323484a3 100644 --- a/src/device/pci_bridge.c +++ b/src/device/pci_bridge.c @@ -28,6 +28,7 @@ #include <86box/device.h> #include <86box/pci.h> #include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> #define PCI_BRIDGE_DEC_21150 0x10110022 #define PCI_BRIDGE_DEC_21152 0x10110024 @@ -93,7 +94,7 @@ pci_bridge_get_bus_index(void *priv) } static void -pci_bridge_write(int func, int addr, uint8_t val, void *priv) +pci_bridge_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { pci_bridge_t *dev = (pci_bridge_t *) priv; @@ -391,7 +392,7 @@ pci_bridge_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -pci_bridge_read(int func, int addr, void *priv) +pci_bridge_read(int func, int addr, UNUSED(int len), void *priv) { const pci_bridge_t *dev = (pci_bridge_t *) priv; uint8_t ret; diff --git a/src/device/vfio.c b/src/device/vfio.c index 2217eb509f..776ded002a 100644 --- a/src/device/vfio.c +++ b/src/device/vfio.c @@ -246,12 +246,12 @@ vfio_log(const char *fmt, ...) #endif static uint8_t vfio_bar_gettype(vfio_device_t *dev, vfio_region_t *bar); -static uint8_t vfio_config_readb(int func, int addr, void *priv); -static uint16_t vfio_config_readw(int func, int addr, void *priv); -static uint32_t vfio_config_readl(int func, int addr, void *priv); -static void vfio_config_writeb(int func, int addr, uint8_t val, void *priv); -static void vfio_config_writew(int func, int addr, uint16_t val, void *priv); -static void vfio_config_writel(int func, int addr, uint32_t val, void *priv); +static uint8_t vfio_config_readb(int func, int addr, int len, void *priv); +static uint16_t vfio_config_readw(int func, int addr, int len, void *priv); +static uint32_t vfio_config_readl(int func, int addr, int len, void *priv); +static void vfio_config_writeb(int func, int addr, int len, uint8_t val, void *priv); +static void vfio_config_writew(int func, int addr, int len, uint16_t val, void *priv); +static void vfio_config_writel(int func, int addr, int len, uint32_t val, void *priv); static void vfio_irq_intx_setpin(vfio_device_t *dev); static void vfio_irq_msi_disable(vfio_device_t *dev); static void vfio_irq_msix_disable(vfio_device_t *dev); @@ -371,7 +371,7 @@ vfio_quirk_configmirror_readb(uint32_t addr, void *priv) vfio_mem_readb_fd(addr, bar); /* Read configuration register. */ - uint8_t ret = vfio_config_readb(0, addr - bar->quirks.configmirror.offset, dev); + uint8_t ret = vfio_config_readb(0, addr - bar->quirks.configmirror.offset, 1, dev); vfio_log_op("VFIO %s: Config mirror: Read %02X from index %02X\n", dev->name, ret, addr - bar->quirks.configmirror.offset); @@ -388,7 +388,7 @@ vfio_quirk_configmirror_readw(uint32_t addr, void *priv) vfio_mem_readw_fd(addr, bar); /* Read configuration register. */ - uint16_t ret = vfio_config_readw(0, addr - bar->quirks.configmirror.offset, dev); + uint16_t ret = vfio_config_readw(0, addr - bar->quirks.configmirror.offset, 2, dev); vfio_log_op("VFIO %s: Config mirror: Read %04X from index %02X\n", dev->name, ret, addr - bar->quirks.configmirror.offset); @@ -405,7 +405,7 @@ vfio_quirk_configmirror_readl(uint32_t addr, void *priv) vfio_mem_readl_fd(addr, bar); /* Read configuration register. */ - uint32_t ret = vfio_config_readl(0, addr - bar->quirks.configmirror.offset, dev); + uint32_t ret = vfio_config_readl(0, addr - bar->quirks.configmirror.offset, 4, dev); vfio_log_op("VFIO %s: Config mirror: Read %08X from index %02X\n", dev->name, ret, addr - bar->quirks.configmirror.offset); @@ -421,7 +421,7 @@ vfio_quirk_configmirror_writeb(uint32_t addr, uint8_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: Config mirror: Write %02X to index %02X\n", dev->name, val, addr - bar->quirks.configmirror.offset); - vfio_config_writeb(0, addr - bar->quirks.configmirror.offset, val, dev); + vfio_config_writeb(0, addr - bar->quirks.configmirror.offset, 1, val, dev); } static void @@ -433,7 +433,7 @@ vfio_quirk_configmirror_writew(uint32_t addr, uint16_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: Config mirror: Write %04X to index %02X\n", dev->name, val, addr - bar->quirks.configmirror.offset); - vfio_config_writew(0, addr - bar->quirks.configmirror.offset, val, dev); + vfio_config_writew(0, addr - bar->quirks.configmirror.offset, 2, val, dev); } static void @@ -445,7 +445,7 @@ vfio_quirk_configmirror_writel(uint32_t addr, uint32_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: Config mirror: Write %08X to index %02X\n", dev->name, val, addr - bar->quirks.configmirror.offset); - vfio_config_writel(0, addr - bar->quirks.configmirror.offset, val, dev); + vfio_config_writel(0, addr - bar->quirks.configmirror.offset, 4, val, dev); } static void @@ -541,11 +541,11 @@ vfio_quirk_configwindow_data_readb(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ uint32_t index = bar->quirks.configwindow.index; if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { - ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[0].start, dev); + ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[0].start, 1, dev); vfio_log_op("VFIO %s: Config window: Read %02X from primary index %08X\n", dev->name, ret, index); } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { - ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[1].start, dev); + ret = vfio_config_readb(0, index - bar->quirks.configwindow.offset[1].start, 1, dev); vfio_log_op("VFIO %s: Config window: Read %02X from secondary index %08X\n", dev->name, ret, index); } @@ -565,11 +565,11 @@ vfio_quirk_configwindow_data_readw(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ uint32_t index = bar->quirks.configwindow.index; if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { - ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[0].start, dev); + ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[0].start, 2, dev); vfio_log_op("VFIO %s: Config window: Read %04X from primary index %08X\n", dev->name, ret, index); } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { - ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[1].start, dev); + ret = vfio_config_readw(0, index - bar->quirks.configwindow.offset[1].start, 2, dev); vfio_log_op("VFIO %s: Config window: Read %04X from secondary index %08X\n", dev->name, ret, index); } @@ -589,11 +589,11 @@ vfio_quirk_configwindow_data_readl(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ uint32_t index = bar->quirks.configwindow.index; if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { - ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[0].start, dev); + ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[0].start, 4, dev); vfio_log_op("VFIO %s: Config window: Read %08X from primary index %08X\n", dev->name, ret, index); } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { - ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[1].start, dev); + ret = vfio_config_readl(0, index - bar->quirks.configwindow.offset[1].start, 4, dev); vfio_log_op("VFIO %s: Config window: Read %08X from secondary index %08X\n", dev->name, ret, index); } @@ -612,12 +612,12 @@ vfio_quirk_configwindow_data_writeb(uint16_t addr, uint8_t val, void *priv) if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { vfio_log_op("VFIO %s: Config window: Write %02X to primary index %08X\n", dev->name, val, index); - vfio_config_writeb(0, index - bar->quirks.configwindow.offset[0].start, val, dev); + vfio_config_writeb(0, index - bar->quirks.configwindow.offset[0].start, 1, val, dev); return; } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { vfio_log_op("VFIO %s: Config window: Write %02X to secondary index %08X\n", dev->name, val, index); - vfio_config_writeb(0, index - bar->quirks.configwindow.offset[1].start, val, dev); + vfio_config_writeb(0, index - bar->quirks.configwindow.offset[1].start, 1, val, dev); return; } @@ -636,12 +636,12 @@ vfio_quirk_configwindow_data_writew(uint16_t addr, uint16_t val, void *priv) if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { vfio_log_op("VFIO %s: Config window: Write %04X to primary index %08X\n", dev->name, val, index); - vfio_config_writew(0, index - bar->quirks.configwindow.offset[0].start, val, dev); + vfio_config_writew(0, index - bar->quirks.configwindow.offset[0].start, 2, val, dev); return; } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { vfio_log_op("VFIO %s: Config window: Write %04X to secondary index %08X\n", dev->name, val, index); - vfio_config_writew(0, index - bar->quirks.configwindow.offset[1].start, val, dev); + vfio_config_writew(0, index - bar->quirks.configwindow.offset[1].start, 2, val, dev); return; } @@ -660,12 +660,12 @@ vfio_quirk_configwindow_data_writel(uint16_t addr, uint32_t val, void *priv) if ((index >= bar->quirks.configwindow.offset[0].start) && (index <= bar->quirks.configwindow.offset[0].end)) { vfio_log_op("VFIO %s: Config window: Write %08X to primary index %08X\n", dev->name, val, index); - vfio_config_writel(0, index - bar->quirks.configwindow.offset[0].start, val, dev); + vfio_config_writel(0, index - bar->quirks.configwindow.offset[0].start, 4, val, dev); return; } else if ((index >= bar->quirks.configwindow.offset[1].start) && (index <= bar->quirks.configwindow.offset[1].end)) { vfio_log_op("VFIO %s: Config window: Write %08X to secondary index %08X\n", dev->name, val, index); - vfio_config_writel(0, index - bar->quirks.configwindow.offset[1].start, val, dev); + vfio_config_writel(0, index - bar->quirks.configwindow.offset[1].start, 4, val, dev); return; } @@ -1037,7 +1037,7 @@ vfio_quirk_nvidia3d0_data_readb(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ if ((prev_state == NVIDIA_3D0_READ) && (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000))) { - ret = vfio_config_readb(0, dev->quirks.nvidia3d0.index, dev); + ret = vfio_config_readb(0, dev->quirks.nvidia3d0.index, 1, dev); vfio_log_op("VFIO %s: NVIDIA 3D0: Read %02X from index %08X\n", dev->name, ret, dev->quirks.nvidia3d0.index); } @@ -1057,7 +1057,7 @@ vfio_quirk_nvidia3d0_data_readw(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ if ((prev_state == NVIDIA_3D0_READ) && (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000))) { - ret = vfio_config_readw(0, dev->quirks.nvidia3d0.index, dev); + ret = vfio_config_readw(0, dev->quirks.nvidia3d0.index, 2, dev); vfio_log_op("VFIO %s: NVIDIA 3D0: Read %04X from index %08X\n", dev->name, ret, dev->quirks.nvidia3d0.index); } @@ -1077,7 +1077,7 @@ vfio_quirk_nvidia3d0_data_readl(uint16_t addr, void *priv) /* Read configuration register if part of the main PCI configuration space. */ if ((prev_state == NVIDIA_3D0_READ) && (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000))) { - ret = vfio_config_readl(0, dev->quirks.nvidia3d0.index, dev); + ret = vfio_config_readl(0, dev->quirks.nvidia3d0.index, 4, dev); vfio_log_op("VFIO %s: NVIDIA 3D0: Read %08X from index %08X\n", dev->name, ret, dev->quirks.nvidia3d0.index); } @@ -1104,7 +1104,7 @@ vfio_quirk_nvidia3d0_data_writeb(uint16_t addr, uint8_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: NVIDIA 3D0: Write %02X to index %08X\n", dev->name, val, dev->quirks.nvidia3d0.index); - vfio_config_writeb(0, dev->quirks.nvidia3d0.index, val, dev); + vfio_config_writeb(0, dev->quirks.nvidia3d0.index, val, 1, dev); return; } } @@ -1131,7 +1131,7 @@ vfio_quirk_nvidia3d0_data_writew(uint16_t addr, uint16_t val, void *priv) if (((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00001800) || ((dev->quirks.nvidia3d0.index & 0xffffff00) == 0x00088000)) { vfio_log_op("VFIO %s: NVIDIA 3D0: Write %04X to index %08X\n", dev->name, val, dev->quirks.nvidia3d0.index); - vfio_config_writew(0, dev->quirks.nvidia3d0.index, val, dev); + vfio_config_writew(0, dev->quirks.nvidia3d0.index, val, 2, dev); return; } } @@ -1159,7 +1159,7 @@ vfio_quirk_nvidia3d0_data_writel(uint16_t addr, uint32_t val, void *priv) /* Write configuration register. */ vfio_log_op("VFIO %s: NVIDIA 3D0: Write %08X to index %08X\n", dev->name, val, dev->quirks.nvidia3d0.index); - vfio_config_writel(0, dev->quirks.nvidia3d0.index, val, dev); + vfio_config_writel(0, dev->quirks.nvidia3d0.index, val, 4, dev); return; } } @@ -1198,7 +1198,7 @@ vfio_quirk_remap(vfio_device_t *dev, vfio_region_t *bar, uint8_t enable) /* BAR 2 configuration space mirror, and BAR 1/4 configuration space window. */ if (j && !i) { /* QEMU only enables the mirror here if BAR 2 is 64-bit capable. */ - if ((bar->bar_id == 2) && ((vfio_config_readb(0, 0x18, dev) & 0x07) == 0x04)) + if ((bar->bar_id == 2) && ((vfio_config_readb(0, 0x18, 1, dev) & 0x07) == 0x04)) vfio_quirk_configmirror(dev, bar, 0x4000, 0, enable); else if (bar->bar_id == 4) vfio_quirk_configwindow(dev, bar, 0x00, 4, 0x04, 4, 0x4000, 0x4000, enable); @@ -1479,7 +1479,7 @@ ceilpow2(uint32_t size) } static uint8_t -vfio_config_readb(int func, int addr, void *priv) +vfio_config_readb(int func, int addr, UNUSED(int len), void *priv) { vfio_device_t *dev = (vfio_device_t *) priv; if (func) @@ -1602,19 +1602,19 @@ vfio_config_readb(int func, int addr, void *priv) } static uint16_t -vfio_config_readw(int func, int addr, void *priv) +vfio_config_readw(int func, int addr, UNUSED(int len), void *priv) { - return vfio_config_readb(func, addr, priv) | (vfio_config_readb(func, addr + 1, priv) << 8); + return vfio_config_readb(func, addr, 2, priv) | (vfio_config_readb(func, addr + 1, 2, priv) << 8); } static uint32_t -vfio_config_readl(int func, int addr, void *priv) +vfio_config_readl(int func, int addr, UNUSED(int len), void *priv) { - return vfio_config_readb(func, addr, priv) | (vfio_config_readb(func, addr + 1, priv) << 8) | (vfio_config_readb(func, addr + 2, priv) << 16) | (vfio_config_readb(func, addr + 3, priv) << 24); + return vfio_config_readb(func, addr, 4, priv) | (vfio_config_readb(func, addr + 1, 4, priv) << 8) | (vfio_config_readb(func, addr + 2, 4, priv) << 16) | (vfio_config_readb(func, addr + 3, 4, priv) << 24); } static void -vfio_config_writeb(int func, int addr, uint8_t val, void *priv) +vfio_config_writeb(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { vfio_device_t *dev = (vfio_device_t *) priv; if (func) @@ -1850,19 +1850,19 @@ vfio_config_writeb(int func, int addr, uint8_t val, void *priv) } static void -vfio_config_writew(int func, int addr, uint16_t val, void *priv) +vfio_config_writew(int func, int addr, UNUSED(int len), uint16_t val, void *priv) { - vfio_config_writeb(func, addr, val, priv); - vfio_config_writeb(func, addr | 1, val >> 8, priv); + vfio_config_writeb(func, addr, 2, val, priv); + vfio_config_writeb(func, addr | 1, 2, val >> 8, priv); } static void -vfio_config_writel(int func, int addr, uint32_t val, void *priv) +vfio_config_writel(int func, int addr, UNUSED(int len), uint32_t val, void *priv) { - vfio_config_writeb(func, addr, val, priv); - vfio_config_writeb(func, addr | 1, val >> 8, priv); - vfio_config_writeb(func, addr | 2, val >> 16, priv); - vfio_config_writeb(func, addr | 3, val >> 24, priv); + vfio_config_writeb(func, addr, 4, val, priv); + vfio_config_writeb(func, addr | 1, 4, val >> 8, priv); + vfio_config_writeb(func, addr | 2, 4, val >> 16, priv); + vfio_config_writeb(func, addr | 3, 4, val >> 24, priv); } static void @@ -2549,13 +2549,13 @@ vfio_dev_prereset(vfio_device_t *dev) /* Extra steps for devices with power management capability. */ if (dev->pm_cap) { /* Make sure the device is in D0 state. */ - uint8_t pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, dev), + uint8_t pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, 1, dev), state = pm_ctrl & 0x03; if (state) { pm_ctrl &= ~0x03; - vfio_config_writeb(0, dev->pm_cap + 4, pm_ctrl, dev); + vfio_config_writeb(0, dev->pm_cap + 4, pm_ctrl, 1, dev); - pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, dev); + pm_ctrl = vfio_config_readb(0, dev->pm_cap + 4, 1, dev); state = pm_ctrl & 0x03; if (state) vfio_log("VFIO %s: Device stuck in D%d state\n", dev->name, state); @@ -2566,10 +2566,10 @@ vfio_dev_prereset(vfio_device_t *dev) } /* Enable function-level reset if supported. */ - dev->can_flr_reset = (dev->pcie_cap && (vfio_config_readb(0, dev->pcie_cap + 7, dev) & 0x10)) || (dev->af_cap && (vfio_config_readb(0, dev->af_cap + 3, dev) & 0x02)); + dev->can_flr_reset = (dev->pcie_cap && (vfio_config_readb(0, dev->pcie_cap + 7, 1, dev) & 0x10)) || (dev->af_cap && (vfio_config_readb(0, dev->af_cap + 3, 1, dev) & 0x02)); /* Disable bus master, BARs, expansion ROM and VGA regions; also enable INTx. */ - vfio_config_writew(0, 0x04, vfio_config_readw(0, 0x04, dev) & ~0x0407, dev); + vfio_config_writew(0, 0x04, vfio_config_readw(0, 0x04, 2, dev) & ~0x0407, dev); } static void diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index ea2a195d94..44e488df4a 100644 --- a/src/disk/hdc_ide_cmd640.c +++ b/src/disk/hdc_ide_cmd640.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -289,7 +290,7 @@ cmd640_vlb_readl(uint16_t addr, void *priv) } static void -cmd640_pci_write(int func, int addr, uint8_t val, void *priv) +cmd640_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { cmd640_t *dev = (cmd640_t *) priv; @@ -367,7 +368,7 @@ cmd640_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -cmd640_pci_read(int func, int addr, void *priv) +cmd640_pci_read(int func, int addr, UNUSED(int len), void *priv) { cmd640_t *dev = (cmd640_t *) priv; uint8_t ret = 0xff; diff --git a/src/disk/hdc_ide_cmd646.c b/src/disk/hdc_ide_cmd646.c index 333cd5e30d..9cd50e8719 100644 --- a/src/disk/hdc_ide_cmd646.c +++ b/src/disk/hdc_ide_cmd646.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -296,7 +297,7 @@ cmd646_bios_handler(cmd646_t *dev) } static void -cmd646_pci_write(int func, int addr, uint8_t val, void *priv) +cmd646_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { cmd646_t *dev = (cmd646_t *) priv; int reg50 = dev->regs[0x50]; @@ -481,7 +482,7 @@ cmd646_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -cmd646_pci_read(int func, int addr, void *priv) +cmd646_pci_read(int func, int addr, UNUSED(int len), void *priv) { cmd646_t *dev = (cmd646_t *) priv; uint8_t ret = 0xff; diff --git a/src/disk/hdc_ide_rz1000.c b/src/disk/hdc_ide_rz1000.c index 56568cc2c6..7559041b8b 100644 --- a/src/disk/hdc_ide_rz1000.c +++ b/src/disk/hdc_ide_rz1000.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -108,7 +109,7 @@ rz1000_ide_handlers(rz1000_t *dev) } static void -rz1000_pci_write(int func, int addr, uint8_t val, void *priv) +rz1000_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { rz1000_t *dev = (rz1000_t *) priv; @@ -138,7 +139,7 @@ rz1000_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -rz1000_pci_read(int func, int addr, void *priv) +rz1000_pci_read(int func, int addr, UNUSED(int len), void *priv) { rz1000_t *dev = (rz1000_t *) priv; uint8_t ret = 0xff; diff --git a/src/disk/hdc_ide_w83769f.c b/src/disk/hdc_ide_w83769f.c index 25ee16d109..cb4d917788 100644 --- a/src/disk/hdc_ide_w83769f.c +++ b/src/disk/hdc_ide_w83769f.c @@ -30,6 +30,7 @@ #include <86box/mem.h> #include <86box/pci.h> #include <86box/pic.h> +#include <86box/plat_unused.h> #include <86box/timer.h> #include <86box/hdc.h> #include <86box/hdc_ide.h> @@ -233,7 +234,7 @@ w83769f_vlb_readl(uint16_t addr, void *priv) } static void -w83769f_pci_write(int func, int addr, uint8_t val, void *priv) +w83769f_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { w83769f_t *dev = (w83769f_t *) priv; @@ -252,7 +253,7 @@ w83769f_pci_write(int func, int addr, uint8_t val, void *priv) } static uint8_t -w83769f_pci_read(int func, int addr, void *priv) +w83769f_pci_read(int func, int addr, UNUSED(int len), void *priv) { w83769f_t *dev = (w83769f_t *) priv; uint8_t ret = 0xff; diff --git a/src/include/86box/pci.h b/src/include/86box/pci.h index a721db005e..f5f5aee04f 100644 --- a/src/include/86box/pci.h +++ b/src/include/86box/pci.h @@ -266,12 +266,12 @@ extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number); extern void pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, int intd); /* Add a PCI card. */ -extern void pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), - void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot); +extern void pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot); /* Add an instance of the PCI bridge. */ -extern void pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, void *priv), - void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, +extern void pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot); /* Register the cards that have been added into slots. */ diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 3e2e7dd38a..decb23d028 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -799,7 +799,7 @@ nic_update_bios(nic_t *dev) } static uint8_t -nic_pci_read(UNUSED(int func), int addr, void *priv) +nic_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const nic_t *dev = (nic_t *) priv; uint8_t ret = 0x00; @@ -894,7 +894,7 @@ nic_pci_read(UNUSED(int func), int addr, void *priv) } static void -nic_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +nic_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { nic_t *dev = (nic_t *) priv; uint8_t valxor; diff --git a/src/network/net_pcnet.c b/src/network/net_pcnet.c index 2d9aa88bbf..e4cad2552e 100644 --- a/src/network/net_pcnet.c +++ b/src/network/net_pcnet.c @@ -2588,7 +2588,7 @@ pcnet_ioset(nic_t *dev, uint16_t addr, int len) } static void -pcnet_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +pcnet_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { nic_t *dev = (nic_t *) priv; uint8_t valxor; @@ -2671,7 +2671,7 @@ pcnet_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) } static uint8_t -pcnet_pci_read(UNUSED(int func), int addr, void *priv) +pcnet_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const nic_t *dev = (nic_t *) priv; diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 9cc52417fd..5c50f088cc 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3100,7 +3100,7 @@ rtl8139_timer(void *priv) } static uint8_t -rtl8139_pci_read(UNUSED(int func), int addr, void *priv) +rtl8139_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const RTL8139State *s = (RTL8139State *) priv; @@ -3157,7 +3157,7 @@ rtl8139_pci_read(UNUSED(int func), int addr, void *priv) } static void -rtl8139_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +rtl8139_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { RTL8139State *s = (RTL8139State *) priv; diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index 3f1825a1e1..e95810cfa2 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1182,7 +1182,7 @@ tulip_srom_crc(uint8_t *eeprom) } static uint8_t -tulip_pci_read(UNUSED(int func), int addr, void *priv) +tulip_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const TULIPState *s = (TULIPState *) priv; uint8_t ret = 0; @@ -1301,7 +1301,7 @@ tulip_pci_read(UNUSED(int func), int addr, void *priv) } static void -tulip_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +tulip_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { TULIPState *s = (TULIPState *) priv; diff --git a/src/pci.c b/src/pci.c index 16e8cdb4f0..9d08a9e08c 100644 --- a/src/pci.c +++ b/src/pci.c @@ -40,15 +40,15 @@ typedef struct pci_card_t { uint8_t irq_routing[PCI_INT_PINS_NUM]; void * priv; - void (*write)(int func, int addr, uint8_t val, void *priv); - uint8_t (*read)(int func, int addr, void *priv); + void (*write)(int func, int addr, int len, uint8_t val, void *priv); + uint8_t (*read)(int func, int addr, int len, void *priv); } pci_card_t; typedef struct pci_card_desc_t { uint8_t type; void * priv; - void (*write)(int func, int addr, uint8_t val, void *priv); - uint8_t (*read)(int func, int addr, void *priv); + void (*write)(int func, int addr, int len, uint8_t val, void *priv); + uint8_t (*read)(int func, int addr, int len, void *priv); uint8_t *slot; } pci_card_desc_t; @@ -91,6 +91,7 @@ static int pci_card; static int pci_bus; static int pci_key; static int pci_trc_reg = 0; +static int pci_access_len = 0; static uint32_t pci_enable = 0x00000000; static void pci_reset_regs(void); @@ -174,7 +175,7 @@ pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state) return; if (pci_flags & FLAG_NO_IRQ_STEERING) - irq_line = pci_cards[slot].read(0, 0x3c, pci_cards[slot].priv); + irq_line = pci_cards[slot].read(0, 0x3c, 1, pci_cards[slot].priv); else { irq_routing = pci_cards[slot].irq_routing[pci_int_index]; @@ -349,12 +350,12 @@ pci_reg_write(uint16_t port, uint8_t val) slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; if (slot != PCI_CARD_INVALID) { if (pci_cards[slot].write) - pci_cards[slot].write(pci_func, pci_index | (port & 0x03), val, pci_cards[slot].priv); + pci_cards[slot].write(pci_func, pci_index | (port & 0x03), pci_access_len, val, pci_cards[slot].priv); } - pci_log("PCI: [WB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %02X\n", + pci_log("PCI: [WB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X, length %I = %02X\n", (port >= 0xc000) ? 2 : 1, slot, (slot == PCI_CARD_INVALID) ? "non-existent" : (pci_cards[slot].write ? "used" : "unused"), - pci_card, pci_bus, pci_func, pci_index | (port & 0x03), val); + pci_card, pci_bus, pci_func, pci_index | (port & 0x03), pci_access_len, val); } static void @@ -364,6 +365,8 @@ pci_reset_regs(void) pci_enable = 0x00000000; pci_flags &= ~(FLAG_CONFIG_IO_ON | FLAG_CONFIG_M1_IO_ON); + + pci_access_len = 1; } void @@ -496,16 +499,24 @@ pci_writew(uint16_t port, uint16_t val, UNUSED(void *priv)) { if (port & 0x0001) { /* Non-aligned access, split into two byte accesses. */ + if (pci_access_len == 1) + pci_access_len = 2; pci_write(port, val & 0xff, priv); pci_write(port + 1, val >> 8, priv); + if (pci_access_len == 2) + pci_access_len = 1; } else { /* Aligned access, still split because we cheat. */ switch (port) { case 0xcfc: case 0xcfe: case 0xc000 ... 0xcffe: + if (pci_access_len == 1) + pci_access_len = 2; pci_write(port, val & 0xff, priv); pci_write(port + 1, val >> 8, priv); + if (pci_access_len == 2) + pci_access_len = 1; break; default: @@ -519,8 +530,10 @@ pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) { if (port & 0x0003) { /* Non-aligned access, split into two word accesses. */ + pci_access_len = 4; pci_writew(port, val & 0xffff, priv); pci_writew(port + 2, val >> 16, priv); + pci_access_len = 1; } else { /* Aligned access. */ switch (port) { @@ -545,8 +558,10 @@ pci_writel(uint16_t port, uint32_t val, UNUSED(void *priv)) case 0xcfc: case 0xc000 ... 0xcffc: /* Still split because we cheat. */ + pci_access_len = 4; pci_writew(port, val & 0xffff, priv); pci_writew(port + 2, val >> 16, priv); + pci_access_len = 1; break; default: @@ -569,12 +584,12 @@ pci_reg_read(uint16_t port) slot = pci_card_to_slot_mapping[pci_bus_number_to_index_mapping[pci_bus]][pci_card]; if (slot != PCI_CARD_INVALID) { if (pci_cards[slot].read) - ret = pci_cards[slot].read(pci_func, pci_index | (port & 0x03), pci_cards[slot].priv); + ret = pci_cards[slot].read(pci_func, pci_index | (port & 0x03), pci_access_len, pci_cards[slot].priv); } - pci_log("PCI: [RB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X = %02X\n", + pci_log("PCI: [RB] Mechanism #%i, slot %02X, %s card %02X:%02X, function %02X, index %02X, length %i = %02X\n", (port >= 0xc000) ? 2 : 1, slot, (slot == PCI_CARD_INVALID) ? "non-existent" : (pci_cards[slot].read ? "used" : "unused"), - pci_card, pci_bus, pci_func, pci_index | (port & 0x03), ret); + pci_card, pci_bus, pci_access_len, pci_index | (port & 0x03), pci_func, ret); return ret; } @@ -643,8 +658,12 @@ pci_readw(uint16_t port, UNUSED(void *priv)) case 0xcfc: case 0xcfe: case 0xc000 ... 0xcffe: + if (pci_access_len == 1) + pci_access_len = 2; ret = pci_read(port, priv); ret |= ((uint16_t) pci_read(port + 1, priv)) << 8; + if (pci_access_len == 2) + pci_access_len = 1; break; default: @@ -662,8 +681,10 @@ pci_readl(uint16_t port, UNUSED(void *priv)) if (port & 0x0003) { /* Non-aligned access, split into two word accesses. */ + pci_access_len = 4; ret = pci_readw(port, priv); ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + pci_access_len = 1; } else { /* Aligned access. */ switch (port) { @@ -682,8 +703,10 @@ pci_readl(uint16_t port, UNUSED(void *priv)) case 0xcfc: case 0xc000 ... 0xcffc: /* Still split because we cheat. */ + pci_access_len = 4; ret = pci_readw(port, priv); ret |= ((uint32_t) pci_readw(port + 2, priv)) << 16; + pci_access_len = 1; break; } } @@ -781,8 +804,8 @@ pci_find_slot(uint8_t add_type, uint8_t ignore_slot) /* Add a PCI card. */ void -pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), - void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot) +pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot) { pci_card_desc_t *dev; @@ -853,7 +876,8 @@ pci_register_card(int pci_card) /* Add an instance of the PCI bridge. */ void -pci_add_bridge(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv), void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot) +pci_add_bridge(uint8_t add_type, uint8_t (*read)(int func, int addr, int len, void *priv), + void (*write)(int func, int addr, int len, uint8_t val, void *priv), void *priv, uint8_t *slot) { pci_card_t *card; uint8_t bridge_slot = (add_type == PCI_ADD_NORMAL) ? last_normal_pci_card_id : pci_find_slot(add_type, 0xff); diff --git a/src/pci_dummy.c b/src/pci_dummy.c index bceb58c22d..e5395bed87 100644 --- a/src/pci_dummy.c +++ b/src/pci_dummy.c @@ -38,7 +38,7 @@ pci_dummy_interrupt(int set, pci_dummy_t *dev) } static uint8_t -pci_dummy_read(uint16_t port, void *priv) +pci_dummy_read(uint16_t port, UNUSED(int len), void *priv) { pci_dummy_t *dev = (pci_dummy_t *) priv; uint8_t ret = 0xff; @@ -90,7 +90,7 @@ pci_dummy_readl(uint16_t port, void *priv) } static void -pci_dummy_write(uint16_t port, UNUSED(uint8_t val), void *priv) +pci_dummy_write(uint16_t port, UNUSED(uint8_t val), UNUSED(int len), void *priv) { pci_dummy_t *dev = (pci_dummy_t *) priv; diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index daeb0a3e4c..754750b22d 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1117,7 +1117,7 @@ BuslogicBIOSUpdate(buslogic_data_t *bl) } static uint8_t -BuslogicPCIRead(UNUSED(int func), int addr, void *priv) +BuslogicPCIRead(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const x54x_t *dev = (x54x_t *) priv; #ifdef ENABLE_BUSLOGIC_LOG @@ -1203,7 +1203,7 @@ BuslogicPCIRead(UNUSED(int func), int addr, void *priv) } static void -BuslogicPCIWrite(UNUSED(int func), int addr, uint8_t val, void *priv) +BuslogicPCIWrite(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { x54x_t *dev = (x54x_t *) priv; buslogic_data_t *bl = (buslogic_data_t *) dev->ven_data; diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index bc3ecec0ba..eef94c916e 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -2283,7 +2283,7 @@ uint8_t ncr53c8xx_pci_regs[256]; bar_t ncr53c8xx_pci_bar[4]; static uint8_t -ncr53c8xx_pci_read(UNUSED(int func), int addr, void *priv) +ncr53c8xx_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; @@ -2387,7 +2387,7 @@ ncr53c8xx_pci_read(UNUSED(int func), int addr, void *priv) } static void -ncr53c8xx_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +ncr53c8xx_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { ncr53c8xx_t *dev = (ncr53c8xx_t *) priv; uint8_t valxor; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 11793f5a93..51aea3f46d 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -1997,7 +1997,7 @@ esp_bios_disable(esp_t *dev) #define EE_ADAPT_OPTION_SCAM_SUPPORT 0x08 static uint8_t -esp_pci_read(UNUSED(int func), int addr, void *priv) +esp_pci_read(UNUSED(int func), int addr, int len, void *priv) { esp_t *dev = (esp_t *) priv; @@ -2009,12 +2009,15 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) if (!dev->has_bios || dev->local) return 0x22; else { - if (nmc93cxx_eeprom_read(dev->eeprom)) - return 0x22; - else { - dev->eeprom->dev.out = 1; - return 2; + uint8_t ret = 0x22; + + if (len == 1) { + /* First byte of address space is AND-ed with EEPROM DO line */ + if (!nmc93cxx_eeprom_read(dev->eeprom)) + ret &= 0x00; } + + return ret; } break; case 0x01: @@ -2084,7 +2087,7 @@ esp_pci_read(UNUSED(int func), int addr, void *priv) } static void -esp_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +esp_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { esp_t *dev = (esp_t *) priv; uint8_t valxor; diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 23c4863c76..9a4cb3c6ff 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -1905,7 +1905,7 @@ update_legacy(es137x_t *dev, uint32_t old_legacy_ctrl) } static uint8_t -es1370_pci_read(int func, int addr, void *priv) +es1370_pci_read(int func, int addr, UNUSED(int len), void *priv) { const es137x_t *dev = (es137x_t *) priv; @@ -2001,7 +2001,7 @@ es1370_pci_read(int func, int addr, void *priv) } static uint8_t -es1371_pci_read(int func, int addr, void *priv) +es1371_pci_read(int func, int addr, UNUSED(int len), void *priv) { const es137x_t *dev = (es137x_t *) priv; @@ -2103,7 +2103,7 @@ es137x_io_set(es137x_t *dev, int set) } static void -es1370_pci_write(int func, int addr, uint8_t val, void *priv) +es1370_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { es137x_t *dev = (es137x_t *) priv; @@ -2154,7 +2154,7 @@ es1370_pci_write(int func, int addr, uint8_t val, void *priv) } static void -es1371_pci_write(int func, int addr, uint8_t val, void *priv) +es1371_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { es137x_t *dev = (es137x_t *) priv; diff --git a/src/sound/snd_cmi8x38.c b/src/sound/snd_cmi8x38.c index 9ee003689e..d4490ac239 100644 --- a/src/sound/snd_cmi8x38.c +++ b/src/sound/snd_cmi8x38.c @@ -966,7 +966,7 @@ cmi8x38_remap(cmi8x38_t *dev) } static uint8_t -cmi8x38_pci_read(int func, int addr, void *priv) +cmi8x38_pci_read(int func, int addr, UNUSED(int len), void *priv) { const cmi8x38_t *dev = (cmi8x38_t *) priv; uint8_t ret = 0xff; @@ -980,7 +980,7 @@ cmi8x38_pci_read(int func, int addr, void *priv) } static void -cmi8x38_pci_write(int func, int addr, uint8_t val, void *priv) +cmi8x38_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { cmi8x38_t *dev = (cmi8x38_t *) priv; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index ceaf4224b8..8ce13f14d3 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -5129,7 +5129,7 @@ mach64_writel_be(uint32_t addr, uint32_t val, void *priv) } uint8_t -mach64_pci_read(UNUSED(int func), int addr, void *priv) +mach64_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const mach64_t *mach64 = (mach64_t *) priv; @@ -5214,7 +5214,7 @@ mach64_pci_read(UNUSED(int func), int addr, void *priv) } void -mach64_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +mach64_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { mach64_t *mach64 = (mach64_t *) priv; diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index ccb1941460..fff9bce3ec 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -7092,7 +7092,7 @@ ati8514_pos_write(uint16_t port, uint8_t val, void *priv) } static uint8_t -mach32_pci_read(UNUSED(int func), int addr, void *priv) +mach32_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const mach_t *mach = (mach_t *) priv; uint8_t ret = 0x00; @@ -7171,7 +7171,7 @@ mach32_pci_read(UNUSED(int func), int addr, void *priv) } static void -mach32_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +mach32_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { mach_t *mach = (mach_t *) priv; if ((addr >= 0x30) && (addr <= 0x33) && !mach->has_bios) diff --git a/src/video/vid_bochs_vbe.c b/src/video/vid_bochs_vbe.c index 0a41bec2d5..d14e92ec13 100644 --- a/src/video/vid_bochs_vbe.c +++ b/src/video/vid_bochs_vbe.c @@ -39,6 +39,7 @@ #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> #include <86box/pci.h> +#include <86box/plat_unused.h> #include <86box/i2c.h> #include <86box/vid_ddc.h> @@ -628,7 +629,7 @@ bochs_vbe_in(uint16_t addr, void *priv) } static uint8_t -bochs_vbe_pci_read(const int func, const int addr, void *priv) +bochs_vbe_pci_read(const int func, const int addr, UNUSED(const int len), void *priv) { const bochs_vbe_t *dev = (bochs_vbe_t *) priv; uint8_t ret = 0x00; @@ -711,7 +712,7 @@ bochs_vbe_disable_handlers(bochs_vbe_t *dev) } static void -bochs_vbe_pci_write(const int func, const int addr, const uint8_t val, void *priv) +bochs_vbe_pci_write(const int func, const int addr, UNUSED(const int len), const uint8_t val, void *priv) { bochs_vbe_t *dev = (bochs_vbe_t *) priv; diff --git a/src/video/vid_chips_69000.c b/src/video/vid_chips_69000.c index ef48207e15..2cd6c41620 100644 --- a/src/video/vid_chips_69000.c +++ b/src/video/vid_chips_69000.c @@ -2141,7 +2141,7 @@ chips_69000_in(uint16_t addr, void *priv) } static uint8_t -chips_69000_pci_read(UNUSED(int func), int addr, void *priv) +chips_69000_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { chips_69000_t *chips = (chips_69000_t *) priv; uint8_t ret = 0x00; @@ -2215,7 +2215,7 @@ chips_69000_pci_read(UNUSED(int func), int addr, void *priv) } static void -chips_69000_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +chips_69000_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { chips_69000_t *chips = (chips_69000_t *) priv; diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 4161e223e8..cec60332e2 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -3934,7 +3934,7 @@ gd54xx_start_blit(uint32_t cpu_dat, uint32_t count, gd54xx_t *gd54xx, svga_t *sv } static uint8_t -cl_pci_read(UNUSED(int func), int addr, void *priv) +cl_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const gd54xx_t *gd54xx = (gd54xx_t *) priv; const svga_t *svga = &gd54xx->svga; @@ -4046,7 +4046,7 @@ cl_pci_read(UNUSED(int func), int addr, void *priv) } static void -cl_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +cl_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { gd54xx_t *gd54xx = (gd54xx_t *) priv; const svga_t *svga = &gd54xx->svga; diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 4abb9a7676..18d6b4575d 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2652,7 +2652,7 @@ et4000w32p_io_set(et4000w32p_t *et4000) } uint8_t -et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) +et4000w32p_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const et4000w32p_t *et4000 = (et4000w32p_t *) priv; @@ -2709,7 +2709,7 @@ et4000w32p_pci_read(UNUSED(int func), int addr, void *priv) } void -et4000w32p_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +et4000w32p_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { et4000w32p_t *et4000 = (et4000w32p_t *) priv; svga_t *svga = &et4000->svga; diff --git a/src/video/vid_mga.c b/src/video/vid_mga.c index 07b0869f79..449b21866b 100644 --- a/src/video/vid_mga.c +++ b/src/video/vid_mga.c @@ -6337,7 +6337,7 @@ mystique_tvp3026_gpio_write(uint8_t cntl, uint8_t data, void *priv) } static uint8_t -mystique_pci_read(UNUSED(int func), int addr, void *priv) +mystique_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { mystique_t *mystique = (mystique_t *) priv; uint8_t ret = 0x00; @@ -6574,7 +6574,7 @@ mystique_pci_read(UNUSED(int func), int addr, void *priv) } static void -mystique_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +mystique_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { mystique_t *mystique = (mystique_t *) priv; diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index fc7499ff66..3965391cb9 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -458,8 +458,8 @@ static void s3_accel_out_l(uint16_t port, uint32_t val, void *priv); static uint8_t s3_accel_in(uint16_t port, void *priv); static uint16_t s3_accel_in_w(uint16_t port, void *priv); static uint32_t s3_accel_in_l(uint16_t port, void *priv); -static uint8_t s3_pci_read(int func, int addr, void *priv); -static void s3_pci_write(int func, int addr, uint8_t val, void *priv); +static uint8_t s3_pci_read(int func, int addr, int len, void *priv); +static void s3_pci_write(int func, int addr, int len, uint8_t val, void *priv); #ifdef ENABLE_S3_LOG int s3_do_log = ENABLE_S3_LOG; @@ -2013,7 +2013,7 @@ s3_accel_write_fifo(s3_t *s3, uint32_t addr, uint8_t val) int addr_lo = addr & 1; if (svga->crtc[0x53] & 0x08) { if ((addr >= 0x08000) && (addr <= 0x0803f)) - s3_pci_write(0, addr & 0xff, val, s3); + s3_pci_write(0, addr & 0xff, 1, val, s3); } switch (addr & 0x1fffe) { @@ -6736,7 +6736,7 @@ s3_accel_read(uint32_t addr, void *priv) if (svga->crtc[0x53] & 0x08) { if ((addr >= 0x08000) && (addr <= 0x0803f)) - return s3_pci_read(0, addr & 0xff, s3); + return s3_pci_read(0, addr & 0xff, 1, s3); switch (addr & 0x1ffff) { case 0x83b0 ... 0x83df: return s3_in(addr & 0x3ff, s3); @@ -11001,7 +11001,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, voi } static uint8_t -s3_pci_read(UNUSED(int func), int addr, void *priv) +s3_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const s3_t *s3 = (s3_t *) priv; const svga_t *svga = &s3->svga; @@ -11090,7 +11090,7 @@ s3_pci_read(UNUSED(int func), int addr, void *priv) } static void -s3_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +s3_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index abeba064ec..b53dd5e8cc 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -5024,7 +5024,7 @@ s3_virge_overlay_draw(svga_t *svga, int displine) } static uint8_t -s3_virge_pci_read(UNUSED(int func), int addr, void *priv) +s3_virge_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const virge_t *virge = (virge_t *) priv; const svga_t *svga = &virge->svga; @@ -5189,7 +5189,7 @@ s3_virge_pci_read(UNUSED(int func), int addr, void *priv) } static void -s3_virge_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +s3_virge_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { virge_t *virge = (virge_t *) priv; svga_t *svga = &virge->svga; diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 28c02363c7..2a76ee2a45 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -1096,7 +1096,7 @@ tgui_hwcursor_draw(svga_t *svga, int displine) } uint8_t -tgui_pci_read(UNUSED(int func), int addr, void *priv) +tgui_pci_read(UNUSED(int func), int addr, UNUSED(int len), void *priv) { const tgui_t *tgui = (tgui_t *) priv; @@ -1166,7 +1166,7 @@ tgui_pci_read(UNUSED(int func), int addr, void *priv) } void -tgui_pci_write(UNUSED(int func), int addr, uint8_t val, void *priv) +tgui_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *priv) { tgui_t *tgui = (tgui_t *) priv; svga_t *svga = &tgui->svga; diff --git a/src/video/vid_voodoo.c b/src/video/vid_voodoo.c index 72a57e66c7..78aba3cadd 100644 --- a/src/video/vid_voodoo.c +++ b/src/video/vid_voodoo.c @@ -1005,7 +1005,7 @@ voodoo_recalcmapping(voodoo_set_t *set) } uint8_t -voodoo_pci_read(int func, int addr, void *priv) +voodoo_pci_read(int func, int addr, UNUSED(int len), void *priv) { const voodoo_t *voodoo = (voodoo_t *) priv; @@ -1069,7 +1069,7 @@ voodoo_pci_read(int func, int addr, void *priv) } void -voodoo_pci_write(int func, int addr, uint8_t val, void *priv) +voodoo_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { voodoo_t *voodoo = (voodoo_t *) priv; diff --git a/src/video/vid_voodoo_banshee.c b/src/video/vid_voodoo_banshee.c index f914c7e866..f6f0476ad0 100644 --- a/src/video/vid_voodoo_banshee.c +++ b/src/video/vid_voodoo_banshee.c @@ -3066,7 +3066,7 @@ banshee_vsync_callback(svga_t *svga) } static uint8_t -banshee_pci_read(int func, int addr, void *priv) +banshee_pci_read(int func, int addr, UNUSED(int len), void *priv) { const banshee_t *banshee = (banshee_t *) priv; #if 0 @@ -3276,7 +3276,7 @@ banshee_pci_read(int func, int addr, void *priv) } static void -banshee_pci_write(int func, int addr, uint8_t val, void *priv) +banshee_pci_write(int func, int addr, UNUSED(int len), uint8_t val, void *priv) { banshee_t *banshee = (banshee_t *) priv; #if 0 From 01779aaf4edefb91b9ed9d2c49fe418c31174d8c Mon Sep 17 00:00:00 2001 From: kotochi98 <185547947+kotochi98@users.noreply.github.com> Date: Sat, 24 Jan 2026 13:49:46 +0300 Subject: [PATCH 39/58] Add the beta evaluation BIOS for the MiTAC 6110zu and set the R804 retail BIOS as the default --- src/machine/m_at_slot1.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 713ab09c05..cbd0cdec5f 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -1431,20 +1431,20 @@ static const device_config_t vei8_config[] = { .name = "bios", .description = "BIOS Version", .type = CONFIG_BIOS, - .default_string = "vei8", + .default_string = "6110zu", .default_int = 0, .file_filter = NULL, .spinner = { 0 }, .selection = { { 0 } }, .bios = { { - .name = "Award Modular BIOS v6.00PG - Revision QHW.10.01 (HP Sherwood-B)", - .internal_name = "vei8", + .name = "Award Modular BIOS v6.00PG - Revision 61100003 (beta)", + .internal_name = "6110zu0003", .bios_type = BIOS_NORMAL, .files_no = 1, .local = 0, .size = 262144, - .files = { "roms/machines/vei8/QHW1001.BIN", "" } + .files = { "roms/machines/vei8/61100003.BIN", "" } }, { .name = "Award Modular BIOS v6.00PG - Revision R804", @@ -1455,6 +1455,15 @@ static const device_config_t vei8_config[] = { .size = 262144, .files = { "roms/machines/vei8/r804.bin", "" } }, + { + .name = "Award Modular BIOS v6.00PG - Revision QHW.10.01 (HP Sherwood-B)", + .internal_name = "vei8", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 262144, + .files = { "roms/machines/vei8/QHW1001.BIN", "" } + }, { .files_no = 0 } } }, From 6d668558dccc59a9f44d1c37530e8753cc3ae78f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Jan 2026 16:25:21 +0100 Subject: [PATCH 40/58] NMC 93cXX EEPROM: Remove the left-over NULL check in nmc_93cxx_eeperom_data(). --- src/mem/nmc93cxx.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mem/nmc93cxx.c b/src/mem/nmc93cxx.c index 17d97591ed..dada964547 100644 --- a/src/mem/nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -265,8 +265,6 @@ nmc93cxx_eeprom_close(void *priv) uint16_t * nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) { - if (UNLIKELY(eeprom == NULL)) - return NULL; /* Get EEPROM data array. */ return &eeprom->dev.data[0]; } From fb03df6feb446440c27b552e0c4be9eccc523bbb Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 24 Jan 2026 17:55:20 +0100 Subject: [PATCH 41/58] Cirrus Logic: Reintroduce the thunks to SVGA reads/writes removed in build 5479, fixes E-Ten Chinese System. --- src/video/vid_cl54xx.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index cec60332e2..089b2ec7ff 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -2288,8 +2288,14 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) xga_write_test(addr, val, svga); + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + svga_write(addr, val, svga); + return; + } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; + svga_write_linear(addr, val, svga); } @@ -2312,6 +2318,11 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) xga_write_test(addr, val, svga); xga_write_test(addr + 1, val >> 8, svga); + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + svga_writew(addr, val, svga); + return; + } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2346,6 +2357,11 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) xga_write_test(addr + 2, val >> 16, svga); xga_write_test(addr + 3, val >> 24, svga); + if ((svga->seqregs[0x07] & 0x01) == 0) { + svga_writel(addr, val, svga); + return; + } + addr &= svga->banked_mask; addr = (addr & 0x7fff) + svga->extra_banks[(addr >> 15) & 1]; @@ -2898,6 +2914,9 @@ gd54xx_read(uint32_t addr, void *priv) svga_t *svga = (svga_t *) priv; gd54xx_t *gd54xx = (gd54xx_t *) svga->local; + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + return svga_read(addr, svga); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) return gd54xx_mem_sys_dest_read(gd54xx, 0); @@ -2916,6 +2935,9 @@ gd54xx_readw(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) svga->local; uint16_t ret; + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + return svga_readw(addr, svga); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, svga); @@ -2938,6 +2960,9 @@ gd54xx_readl(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) svga->local; uint32_t ret; + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + return svga_readl(addr, svga); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, svga); From f491069512eeae3b8f3d6c88e4619484e176bc3b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Jan 2026 00:46:42 +0100 Subject: [PATCH 42/58] Trident TGUI: Remove excess logging. --- src/video/vid_tgui9440.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_tgui9440.c b/src/video/vid_tgui9440.c index 2a76ee2a45..f91fc3f961 100644 --- a/src/video/vid_tgui9440.c +++ b/src/video/vid_tgui9440.c @@ -784,7 +784,7 @@ tgui_recalctimings(svga_t *svga) else if (svga->gdcreg[0xf] & 0x40) svga->clock *= 3.0; - pclog("GDCREGF=%02x, miscout=%02x.\n", svga->gdcreg[0xf] & 0x48, svga->miscout & 0x0c); + // pclog("GDCREGF=%02x, miscout=%02x.\n", svga->gdcreg[0xf] & 0x48, svga->miscout & 0x0c); } else { //pclog("TGUI9400CXi: Clock double=%d.\n", (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8))); switch (((svga->miscout >> 2) & 3) | ((tgui->newctrl2 << 2) & 4) | ((tgui->newctrl2 >> 3) & 8)) { From ca37758018206ba764d867dd44e95258a24454c2 Mon Sep 17 00:00:00 2001 From: Dmitry Borisov Date: Sun, 25 Jan 2026 08:40:56 +0600 Subject: [PATCH 43/58] nmc93cxx: Rewrite the nmc93cxx emulation This patch rewrites the nmc93cxx emulation code. The primary aim of the rewrite is to fix the Qlogic 1080 BIOS v1.11 flashing feature (the card utilizes a 93C56 chip in 128x16 mode). This work is derived from the MAME serial EEPROM emulation code written by Aaron Giles and published under BSD-3-Clause license. https://github.com/mamedev/mame/blob/master/src/devices/machine/eepromser.cpp The code is modelled on the MAME code with the following differences: - Removed support for the ER5911 and MSM16911 EEPROM devices. - Removed support for the X24C44 NOVRAM device. - Removed support for the Seiko S-29X90 EEPROM devices. The 86Box changes: - The nmc93cxx code now also supports EEPROM devices in 8-bit mode. - Make the default_content parameter optional. - Make the nmc93cxx_eeprom_data function to return a const pointer. --- src/include/86box/nmc93cxx.h | 79 +++- src/mem/nmc93cxx.c | 763 +++++++++++++++++++++++++++-------- src/network/net_ne2000.c | 17 +- src/network/net_rtl8139.c | 8 +- src/network/net_tulip.c | 8 +- src/scsi/scsi_pcscsi.c | 15 +- src/video/vid_s3.c | 6 +- 7 files changed, 668 insertions(+), 228 deletions(-) diff --git a/src/include/86box/nmc93cxx.h b/src/include/86box/nmc93cxx.h index dd02b2d061..b8c9d61b64 100644 --- a/src/include/86box/nmc93cxx.h +++ b/src/include/86box/nmc93cxx.h @@ -1,25 +1,72 @@ -#include <86box/vid_ati_eeprom.h> +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Header of the emulation of the National Semiconductors NMC93Cxx EEPROMs + * (16 bits or 8 bits). + * + * Authors: Cacodemon345 + * + * Copyright 2023 Cacodemon345 + */ +#pragma once -typedef struct nmc93cxx_eeprom_t { - ati_eeprom_t dev; - uint8_t addrbits; - uint16_t size; - char filename[1024]; -} nmc93cxx_eeprom_t; +/* Forward declaration to hide internal device state from users. */ +typedef struct nmc93cxx_eeprom_t nmc93cxx_eeprom_t; +/* EEPROM device type used to specify the size of data array. */ +typedef enum nmc93cxx_eeprom_type { + /* + * Standard 93CX6 class of 16-bit EEPROMs. + * + * Type / Bits per cell / Number of cells + */ + NMC_93C06_x16_16, + NMC_93C46_x16_64, + NMC_93C56_x16_128, + NMC_93C57_x16_128, + NMC_93C66_x16_256, + NMC_93C76_x16_512, + NMC_93C86_x16_1024, + + /* + * Some manufacturers use pin 6 as an "ORG" pin which, + * when pulled low, configures memory for 8-bit accesses. + * + * Type / Bits per cell / Number of cells + */ + NMC_93C46_x8_128, + NMC_93C56_x8_256, + NMC_93C57_x8_256, + NMC_93C66_x8_512, + NMC_93C76_x8_1024, + NMC_93C86_x8_2048, +} nmc93cxx_eeprom_type; + +/* EEPROM device parameters. */ typedef struct nmc93cxx_eeprom_params_t { - uint16_t nwords; - char *filename; - uint16_t *default_content; + /* Device type */ + nmc93cxx_eeprom_type type; + /* Name of EEPROM image file */ + const char *filename; + /* + * Optional pointer to the default data buffer. + * The buffer size should match the size of EEPROM data array specified by nmc93cxx_eeprom_type. + */ + const void *default_content; } nmc93cxx_eeprom_params_t; -/* Read from the EEPROM. */ -uint16_t nmc93cxx_eeprom_read(nmc93cxx_eeprom_t *eeprom); +/* Read the state of the data output (DO) line. */ +bool nmc93cxx_eeprom_read(nmc93cxx_eeprom_t *dev); -/* Write to the EEPROM. */ -void nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi); +/* Set the state of the input lines. */ +void nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *dev, bool eecs, bool eesk, bool eedi); -/* Get EEPROM data array. */ -uint16_t *nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom); +/* Returns pointer to the current EEPROM data array. */ +const uint16_t *nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *dev); extern const device_t nmc93cxx_device; diff --git a/src/mem/nmc93cxx.c b/src/mem/nmc93cxx.c index dada964547..c998fb825c 100644 --- a/src/mem/nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -6,267 +6,676 @@ * * This file is part of the 86Box distribution. * - * Emulation of National Semiconductors NMC93Cxx EEPROMs. + * Emulation of National Semiconductors NMC93Cxx EEPROMs (16 bits or 8 bits). * * Authors: Cacodemon345 * * Copyright 2023 Cacodemon345 */ -/* Ported over from QEMU */ +/* Ported over from the MAME eepromser.cpp implementation. Copyright 2013 Aaron Giles */ + +#ifdef ENABLE_NMC93CXX_EEPROM_LOG +#include +#endif #include #include +#include #include #include -#include +#include #include #include -#define HAVE_STDARG_H +#include + #include <86box/86box.h> #include <86box/device.h> #include <86box/timer.h> #include <86box/nvr.h> +#include <86box/log.h> #include <86box/nmc93cxx.h> #include <86box/plat_unused.h> +#define WRITE_TIME_US 1750 +#define WRITE_ALL_TIME_US 8000 +#define ERASE_TIME_US 1000 +#define ERASE_ALL_TIME_US 8000 + +typedef enum EepromCommand { + COMMAND_INVALID, + COMMAND_READ, + COMMAND_WRITE, + COMMAND_ERASE, + COMMAND_LOCK, + COMMAND_UNLOCK, + COMMAND_WRITEALL, + COMMAND_ERASEALL, + COMMAND_COPY_EEPROM_TO_RAM, + COMMAND_COPY_RAM_TO_EEPROM +} EepromCommand; + +typedef enum EepromState { + STATE_IN_RESET, + STATE_WAIT_FOR_START_BIT, + STATE_WAIT_FOR_COMMAND, + STATE_READING_DATA, + STATE_WAIT_FOR_DATA, + STATE_WAIT_FOR_COMPLETION +} EepromState; + +typedef enum EepromEvent { + EVENT_CS_RISING_EDGE = 1 << 0, + EVENT_CS_FALLING_EDGE = 1 << 1, + EVENT_CLK_RISING_EDGE = 1 << 2, + EVENT_CLK_FALLING_EDGE = 1 << 3 +} EepromEvent; + +struct nmc93cxx_eeprom_t { + /* Command completion timer */ + pc_timer_t cmd_complete_timer; + /* Write tick */ + uint32_t write_tick; + /* State of the CS line */ + bool cs_state; + /* State of the CLK line */ + bool clk_state; + /* State of the DI line */ + bool di_state; + /* READY/BUSY status during a programming operation */ + bool is_busy; + /* Internal device state */ + EepromState state; + /* Accumulator of command+address bits */ + uint32_t command_address_accum; + /* Current address extracted from command */ + uint32_t address; + /* Holds data coming in/going out */ + uint32_t shift_register; + /* Number of bits accumulated */ + uint32_t bits_accum; + /* Current command */ + EepromCommand command; + /* Number of memory cells */ + uint16_t cells; + /* Number of bits per cell */ + uint16_t data_bits; + /* Number of address bits in a command */ + uint8_t command_address_bits; + /* Number of address bits in an address */ + uint8_t address_bits; + /* Are we locked against writes? */ + bool is_locked; + /* Tick of the last CS rising edge */ + uint32_t last_cs_rising_edge_tick; + /* Device logging */ + void *log; + /* Name of EEPROM image file */ + char filename[1024]; + + /* EEPROM image words, must be the last structure member */ + uint16_t array_data[]; +}; + #ifdef ENABLE_NMC93CXX_EEPROM_LOG int nmc93cxx_eeprom_do_log = ENABLE_NMC93CXX_EEPROM_LOG; static void -nmc93cxx_eeprom_log(int lvl, const char *fmt, ...) +nmc93cxx_eeprom_log(nmc93cxx_eeprom_t *dev, int lvl, const char *fmt, ...) { va_list ap; if (nmc93cxx_eeprom_do_log >= lvl) { va_start(ap, fmt); - pclog_ex(fmt, ap); + log_out(dev->log, fmt, ap); va_end(ap); } } #else -# define nmc93cxx_eeprom_log(lvl, fmt, ...) +# define nmc93cxx_eeprom_log(dev, lvl, fmt, ...) #endif +#define MAKE_CASE(x) case x: return #x; +static char* +nmc93cxx_eeprom_state_to_name(EepromState state) +{ + switch (state) { + MAKE_CASE(STATE_IN_RESET); + MAKE_CASE(STATE_WAIT_FOR_START_BIT); + MAKE_CASE(STATE_WAIT_FOR_COMMAND); + MAKE_CASE(STATE_READING_DATA); + MAKE_CASE(STATE_WAIT_FOR_DATA); + MAKE_CASE(STATE_WAIT_FOR_COMPLETION); + default: return ""; + } +} + +static char* +nmc93cxx_eeprom_cmd_to_name(EepromCommand command) +{ + switch (command) { + MAKE_CASE(COMMAND_INVALID); + MAKE_CASE(COMMAND_READ); + MAKE_CASE(COMMAND_WRITE); + MAKE_CASE(COMMAND_ERASE); + MAKE_CASE(COMMAND_LOCK); + MAKE_CASE(COMMAND_UNLOCK); + MAKE_CASE(COMMAND_WRITEALL); + MAKE_CASE(COMMAND_ERASEALL); + MAKE_CASE(COMMAND_COPY_EEPROM_TO_RAM); + MAKE_CASE(COMMAND_COPY_RAM_TO_EEPROM); + default: return ""; + } +} +#undef MAKE_CASE + +static void +nmc93cxx_eeprom_set_state(nmc93cxx_eeprom_t *dev, EepromState state) +{ + if (dev->state != state) { + nmc93cxx_eeprom_log(dev, 2, "EEPROM: New state %s\n", nmc93cxx_eeprom_state_to_name(state)); + } + dev->state = state; +} + +static void +nmc93cxx_eeprom_cmd_complete_timer_callback(void *priv) +{ + nmc93cxx_eeprom_t *dev = priv; + + dev->is_busy = false; +} + +static void +nmc93cxx_eeprom_start_cmd_timer(nmc93cxx_eeprom_t *dev, double period) +{ + dev->is_busy = true; + timer_on_auto(&dev->cmd_complete_timer, period); +} + static void * nmc93cxx_eeprom_init(const device_t *info) { - uint16_t nwords = 64; - uint8_t addrbits = 6; - uint8_t filldefault = 1; nmc93cxx_eeprom_params_t *params_details = (nmc93cxx_eeprom_params_t *) info->local; - nmc93cxx_eeprom_t *eeprom = NULL; - if (info->local == 0) - return NULL; + nmc93cxx_eeprom_t *dev; + bool fill_default = true; + uint16_t cells, nwords, data_bits; + uint8_t addrbits; - nwords = params_details->nwords; + /* Check for mandatory parameters */ + assert(params_details != NULL); + assert(params_details->filename != NULL); - switch (nwords) { - case 16: - case 64: + switch (params_details->type) { + /* 16-bit EEPROMs */ + case NMC_93C06_x16_16: + cells = 16; + addrbits = 6; + data_bits = 16; + break; + case NMC_93C46_x16_64: + cells = 64; addrbits = 6; + data_bits = 16; + break; + case NMC_93C56_x16_128: + cells = 128; + addrbits = 8; + data_bits = 16; + break; + case NMC_93C57_x16_128: + cells = 128; + addrbits = 7; + data_bits = 16; + break; + case NMC_93C66_x16_256: + cells = 256; + addrbits = 8; + data_bits = 16; + break; + case NMC_93C76_x16_512: + cells = 512; + addrbits = 10; + data_bits = 16; + break; + case NMC_93C86_x16_1024: + cells = 1024; + addrbits = 10; + data_bits = 16; break; - case 128: - case 256: + + /* 8-bit EEPROMs */ + case NMC_93C46_x8_128: + cells = 128; + addrbits = 7; + data_bits = 8; + break; + case NMC_93C56_x8_256: + cells = 256; + addrbits = 9; + data_bits = 8; + break; + case NMC_93C57_x8_256: + cells = 256; addrbits = 8; + data_bits = 8; + break; + case NMC_93C66_x8_512: + cells = 512; + addrbits = 9; + data_bits = 8; + break; + case NMC_93C76_x8_1024: + cells = 1024; + addrbits = 11; + data_bits = 8; + break; + case NMC_93C86_x8_2048: + cells = 1024; + addrbits = 11; + data_bits = 8; break; + default: - nwords = 64; - addrbits = 6; + /* Invalid parameter passed to the device */ + assert(false); break; } - eeprom = calloc(1, sizeof(nmc93cxx_eeprom_t) + ((nwords + 1) * 2)); - if (!eeprom) + + /* The "ORG" pin can select the x8 or x16 memory organization */ + if (data_bits == 16) { + nwords = cells; + } else { + nwords = cells / 2; + + assert(data_bits == 8); + } + + dev = calloc(1, offsetof(nmc93cxx_eeprom_t, array_data[nwords])); + if (!dev) return NULL; - eeprom->size = nwords; - eeprom->addrbits = addrbits; - /* Output DO is tristate, read results in 1. */ - eeprom->dev.out = 1; - - if (params_details->filename) { - FILE *fp = nvr_fopen(params_details->filename, "rb"); - strncpy(eeprom->filename, params_details->filename, sizeof(eeprom->filename) - 1); - if (fp) { - filldefault = !fread(eeprom->dev.data, sizeof(uint16_t), nwords, fp); - fclose(fp); - } + dev->cells = cells; + dev->command_address_bits = addrbits; + dev->data_bits = data_bits; + dev->is_locked = true; + dev->command = COMMAND_INVALID; + dev->log = log_open("nmc93cxx"); + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + + /* Load the EEPROM image */ + snprintf(dev->filename, sizeof(dev->filename), "%s", params_details->filename); + FILE *fp = nvr_fopen(dev->filename, "rb"); + if (fp) { + fill_default = !fread(dev->array_data, dev->data_bits / 8, dev->cells, fp); + fclose(fp); + } + if (fill_default && params_details->default_content) { + memcpy(dev->array_data, params_details->default_content, dev->cells * (dev->data_bits / 8)); } - if (filldefault) { - memcpy(eeprom->dev.data, params_details->default_content, nwords * sizeof(uint16_t)); + /* Compute address bits */ + uint32_t count = dev->cells - 1; + dev->address_bits = 0; + while (count != 0) { + count >>= 1; + dev->address_bits++; } - return eeprom; + timer_add(&dev->cmd_complete_timer, nmc93cxx_eeprom_cmd_complete_timer_callback, dev, 0); + + return dev; +} + +static uint32_t +nmc93cxx_eeprom_cell_read(nmc93cxx_eeprom_t *dev, uint32_t address) +{ + if (dev->data_bits == 16) { + return dev->array_data[address]; + } else { + return *((uint8_t *)dev->array_data + address); + } } static void -nmc93cxx_eeprom_save(nmc93cxx_eeprom_t *eeprom) +nmc93cxx_eeprom_cell_write(nmc93cxx_eeprom_t *dev, uint32_t address, uint32_t data) { - FILE *fp = nvr_fopen(eeprom->filename, "wb"); - if (!fp) - return; - fwrite(eeprom->dev.data, 2, eeprom->size, fp); - fclose(fp); + if (dev->data_bits == 16) { + dev->array_data[address] = data; + } else { + *((uint8_t *)dev->array_data + address) = data; + } } -void -nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *eeprom, int eecs, int eesk, int eedi) +static void +nmc93cxx_eeprom_handle_cmd_write(nmc93cxx_eeprom_t *dev, uint32_t address, uint32_t data) { - uint8_t tick = eeprom->dev.count; - uint8_t eedo = eeprom->dev.out; - uint16_t address = eeprom->dev.address; - uint8_t command = eeprom->dev.opcode; - - nmc93cxx_eeprom_log(1, "CS=%u SK=%u DI=%u DO=%u, tick = %u\n", - eecs, eesk, eedi, eedo, tick); - - if (!eeprom->dev.oldena && eecs) { - /* Start chip select cycle. */ - nmc93cxx_eeprom_log(1, "Cycle start, waiting for 1st start bit (0)\n"); - tick = 0; - command = 0x0; - address = 0x0; - } else if (eeprom->dev.oldena && !eecs) { - /* End chip select cycle. This triggers write / erase. */ - if (!eeprom->dev.wp) { - uint8_t subcommand = address >> (eeprom->addrbits - 2); - if (command == 0 && subcommand == 2) { - /* Erase all. */ - for (address = 0; address < eeprom->size; address++) - eeprom->dev.data[address] = 0xffff; - - nmc93cxx_eeprom_save(eeprom); - } else if (command == 3) { - /* Erase word. */ - eeprom->dev.data[address] = 0xffff; - nmc93cxx_eeprom_save(eeprom); - } else if (tick >= (2 + 2 + eeprom->addrbits + 16)) { - if (command == 1) { - /* Write word. */ - eeprom->dev.data[address] &= eeprom->dev.dat; - nmc93cxx_eeprom_save(eeprom); - } else if (command == 0 && subcommand == 1) { - /* Write all. */ - for (address = 0; address < eeprom->size; address++) - eeprom->dev.data[address] &= eeprom->dev.dat; - - nmc93cxx_eeprom_save(eeprom); - } + nmc93cxx_eeprom_log(dev, 1, "EEPROM: WR %08lX <-- %X\n", address, data); + + nmc93cxx_eeprom_cell_write(dev, address, data); + nmc93cxx_eeprom_start_cmd_timer(dev, WRITE_TIME_US); +} + +static void +nmc93cxx_eeprom_handle_cmd_write_all(nmc93cxx_eeprom_t *dev, uint32_t data) +{ + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Write all operation %X\n", data); + + for (uint32_t address = 0; address < (1 << dev->address_bits); ++address) { + nmc93cxx_eeprom_cell_write(dev, address, nmc93cxx_eeprom_cell_read(dev, address) & data); + } + + nmc93cxx_eeprom_start_cmd_timer(dev, WRITE_ALL_TIME_US); +} + +static void +nmc93cxx_eeprom_handle_cmd_erase(nmc93cxx_eeprom_t *dev, uint32_t address) +{ + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Erase data at %08lx\n", address); + + nmc93cxx_eeprom_cell_write(dev, address, ~0); + nmc93cxx_eeprom_start_cmd_timer(dev, ERASE_TIME_US); +} + +static void +nmc93cxx_eeprom_handle_cmd_erase_all(nmc93cxx_eeprom_t *dev) +{ + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Erase all operation\n"); + + for (uint32_t address = 0; address < (1 << dev->address_bits); ++address) { + nmc93cxx_eeprom_cell_write(dev, address, ~0); + } + + nmc93cxx_eeprom_start_cmd_timer(dev, ERASE_ALL_TIME_US); +} + +static void +nmc93cxx_eeprom_parse_command_and_address(nmc93cxx_eeprom_t *dev) +{ + dev->address = dev->command_address_accum & ((1 << dev->command_address_bits) - 1); + + /* Extract the command portion and handle it */ + switch (dev->command_address_accum >> dev->command_address_bits) { + /* Opcode 0 needs two more bits to decode the operation */ + case 0: + switch (dev->address >> (dev->command_address_bits - 2)) { + case 0: dev->command = COMMAND_LOCK; break; + case 1: dev->command = COMMAND_WRITEALL; break; + case 2: dev->command = COMMAND_ERASEALL; break; + case 3: dev->command = COMMAND_UNLOCK; break; } - } - /* Output DO is tristate, read results in 1. */ - eedo = 1; - } else if (eecs && !eeprom->dev.oldclk && eesk) { - /* Raising edge of clock shifts data in. */ - if (tick == 0) { - /* Wait for 1st start bit. */ - if (eedi == 0) { - nmc93cxx_eeprom_log(1, "Got correct 1st start bit, waiting for 2nd start bit (1)\n"); - tick++; - } else { - nmc93cxx_eeprom_log(1, "wrong 1st start bit (is 1, should be 0)\n"); - tick = 2; -#if 0 - ~ assert(!"wrong start bit"); -#endif + dev->address = 0; + break; + + case 1: dev->command = COMMAND_WRITE; break; + case 2: dev->command = COMMAND_READ; break; + case 3: dev->command = COMMAND_ERASE; break; + + default: + dev->command = COMMAND_INVALID; + break; + } + + if (dev->address >= (1 << dev->address_bits)) { + nmc93cxx_eeprom_log(dev, 1, "EEPROM: out-of-range address 0x%X provided (maximum should be 0x%X)\n", dev->address, (1 << dev->address_bits) - 1); + } +} + +static void +nmc93cxx_eeprom_execute_command(nmc93cxx_eeprom_t *dev) +{ + /* Parse into a generic command and reset the accumulator count */ + nmc93cxx_eeprom_parse_command_and_address(dev); + dev->bits_accum = 0; + + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Execute command %s\n", nmc93cxx_eeprom_cmd_to_name(dev->command)); + switch (dev->command) { + /* + * Advance to the READING_DATA state; data is fetched after first CLK + * reset the shift register to 0 to simulate the dummy 0 bit that happens prior + * to the first clock + */ + case COMMAND_READ: + dev->shift_register = 0; + nmc93cxx_eeprom_set_state(dev, STATE_READING_DATA); + break; + + /* Reset the shift register and wait for enough data to be clocked through */ + case COMMAND_WRITE: + case COMMAND_WRITEALL: + dev->shift_register = 0; + nmc93cxx_eeprom_set_state(dev, STATE_WAIT_FOR_DATA); + break; + + /* Erase the parsed address (unless locked) and wait for it to complete */ + case COMMAND_ERASE: + if (dev->is_locked) { + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Attempt to erase while locked\n"); + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; } - } else if (tick == 1) { - /* Wait for 2nd start bit. */ - if (eedi != 0) { - nmc93cxx_eeprom_log(1, "Got correct 2nd start bit, getting command + address\n"); - tick++; - } else { - nmc93cxx_eeprom_log(1, "1st start bit is longer than needed\n"); + nmc93cxx_eeprom_handle_cmd_erase(dev, dev->address); + nmc93cxx_eeprom_set_state(dev, STATE_WAIT_FOR_COMPLETION); + break; + + /* Lock the chip; return to IN_RESET state */ + case COMMAND_LOCK: + dev->is_locked = true; + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; + + /* Unlock the chip; return to IN_RESET state */ + case COMMAND_UNLOCK: + dev->is_locked = false; + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; + + /* Erase the entire chip (unless locked) and wait for it to complete */ + case COMMAND_ERASEALL: + if (dev->is_locked) { + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Attempt to erase all while locked\n"); + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; + } + nmc93cxx_eeprom_handle_cmd_erase_all(dev); + nmc93cxx_eeprom_set_state(dev, STATE_WAIT_FOR_COMPLETION); + break; + + default: + nmc93cxx_eeprom_log(dev, 1, "execute_command called with invalid command %d\n", dev->command); + assert(false); + break; + } +} + +static void +nmc93cxx_eeprom_execute_write_command(nmc93cxx_eeprom_t *dev) +{ + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Execute write command %s\n", nmc93cxx_eeprom_cmd_to_name(dev->command)); + + switch (dev->command) { + /* Reset the shift register and wait for enough data to be clocked through */ + case COMMAND_WRITE: + if (dev->is_locked) { + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Attempt to write to address 0x%X while locked\n", dev->address); + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; } - } else if (tick < 2 + 2) { - /* Got 2 start bits, transfer 2 opcode bits. */ - tick++; - command <<= 1; - if (eedi) { - command += 1; + nmc93cxx_eeprom_handle_cmd_write(dev, dev->address, dev->shift_register); + nmc93cxx_eeprom_set_state(dev, STATE_WAIT_FOR_COMPLETION); + break; + + /* + * Write the entire EEPROM with the same data; ERASEALL is required before so we + * AND against the already-present data + */ + case COMMAND_WRITEALL: + if (dev->is_locked) { + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Attempt to write all while locked\n"); + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; } - } else if (tick < 2 + 2 + eeprom->addrbits) { - /* Got 2 start bits and 2 opcode bits, transfer all address bits. */ - tick++; - address = ((address << 1) | eedi); - if (tick == 2 + 2 + eeprom->addrbits) { - nmc93cxx_eeprom_log(1, "Address = 0x%02x (value 0x%04x)\n", - address, eeprom->dev.data[address]); - if (command == 2) { - eedo = 0; - } - address = address % eeprom->size; - if (command == 0) { - /* Command code in upper 2 bits of address. */ - switch (address >> (eeprom->addrbits - 2)) { - case 0: - nmc93cxx_eeprom_log(1, "write disable command\n"); - eeprom->dev.wp = 1; - break; - case 1: - nmc93cxx_eeprom_log(1, "write all command\n"); - break; - case 2: - nmc93cxx_eeprom_log(1, "erase all command\n"); - break; - case 3: - nmc93cxx_eeprom_log(1, "write enable command\n"); - eeprom->dev.wp = 0; - break; - - default: - break; - } + nmc93cxx_eeprom_handle_cmd_write_all(dev, dev->shift_register); + nmc93cxx_eeprom_set_state(dev, STATE_WAIT_FOR_COMPLETION); + break; + + default: + nmc93cxx_eeprom_log(dev, 1, "execute_command called with invalid command %d\n", dev->command); + assert(false); + break; + } +} + +static void +nmc93cxx_eeprom_handle_event(nmc93cxx_eeprom_t *dev, EepromEvent event) +{ + switch (dev->state) { + /* CS is not asserted; wait for a rising CS to move us forward, ignoring all clocks */ + case STATE_IN_RESET: + if (event == EVENT_CS_RISING_EDGE) + nmc93cxx_eeprom_set_state(dev, STATE_WAIT_FOR_START_BIT); + break; + + /* + * CS is asserted; wait for rising clock with a 1 start bit; falling CS will reset us + * note that because each bit is written independently, it is possible for us to receive + * a false rising CLK edge at the exact same time as a rising CS edge; it appears we + * should ignore these edges (makes sense really) + */ + case STATE_WAIT_FOR_START_BIT: + if ((event == EVENT_CLK_RISING_EDGE) && dev->di_state && !dev->is_busy && (dev->write_tick != dev->last_cs_rising_edge_tick)) { + dev->command_address_accum = 0; + dev->bits_accum = 0; + nmc93cxx_eeprom_set_state(dev, STATE_WAIT_FOR_COMMAND); + } else if (event == EVENT_CS_FALLING_EDGE) + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; + + /* CS is asserted; wait for a command to come through; falling CS will reset us */ + case STATE_WAIT_FOR_COMMAND: + if (event == EVENT_CLK_RISING_EDGE) { + /* If we have enough bits for a command + address, check it out */ + dev->command_address_accum = (dev->command_address_accum << 1) | dev->di_state; + if (++dev->bits_accum == 2 + dev->command_address_bits) + nmc93cxx_eeprom_execute_command(dev); + } else if (event == EVENT_CS_FALLING_EDGE) + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; + + /* CS is asserted; reading data, clock the shift register; falling CS will reset us */ + case STATE_READING_DATA: + if (event == EVENT_CLK_RISING_EDGE) { + uint32_t bit_index = dev->bits_accum++; + + /* Wrapping the address on multi-read */ + if (((bit_index % dev->data_bits) == 0) && (bit_index == 0)) + { + uint32_t addr = (dev->address + dev->bits_accum / dev->data_bits) & ((1 << dev->address_bits) - 1); + uint32_t data = nmc93cxx_eeprom_cell_read(dev, addr); + + nmc93cxx_eeprom_log(dev, 1, "EEPROM: RD %08lX --> %X\n", addr, data); + + dev->shift_register = data << (32 - dev->data_bits); } else { - /* Read, write or erase word. */ - eeprom->dev.dat = eeprom->dev.data[address]; + dev->shift_register = (dev->shift_register << 1) | 1; } + } else if (event == EVENT_CS_FALLING_EDGE) { + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + + if (dev->bits_accum > (dev->data_bits + 1)) + nmc93cxx_eeprom_log(dev, 1, "EEPROM: Overclocked read by %d bits\n", dev->bits_accum - dev->data_bits); + else if (dev->bits_accum < dev->data_bits) + nmc93cxx_eeprom_log(dev, 1, "EEPROM: CS deasserted in READING_DATA after %d bits\n", dev->bits_accum); } - } else if (tick < 2 + 2 + eeprom->addrbits + 16) { - /* Transfer 16 data bits. */ - tick++; - if (command == 2) { - /* Read word. */ - eedo = ((eeprom->dev.dat & 0x8000) != 0); + break; + + /* CS is asserted; waiting for data; clock data through until we accumulate enough; falling CS will reset us */ + case STATE_WAIT_FOR_DATA: + if (event == EVENT_CLK_RISING_EDGE) { + dev->shift_register = (dev->shift_register << 1) | dev->di_state; + if (++dev->bits_accum == dev->data_bits) + nmc93cxx_eeprom_execute_write_command(dev); + } else if (event == EVENT_CS_FALLING_EDGE) { + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + nmc93cxx_eeprom_log(dev, 1, "EEPROM: CS deasserted in STATE_WAIT_FOR_DATA after %d bits\n", dev->bits_accum); } - eeprom->dev.dat <<= 1; - eeprom->dev.dat += eedi; - } else { - nmc93cxx_eeprom_log(1, "additional unneeded tick, not processed\n"); + break; + + /* CS is asserted; waiting for completion; watch for CS falling */ + case STATE_WAIT_FOR_COMPLETION: + if (event == EVENT_CS_FALLING_EDGE) + nmc93cxx_eeprom_set_state(dev, STATE_IN_RESET); + break; + + default: + break; + } +} + +void +nmc93cxx_eeprom_write(nmc93cxx_eeprom_t *dev, bool eecs, bool eesk, bool eedi) +{ + assert(dev != NULL); + + dev->write_tick++; + + nmc93cxx_eeprom_log(dev, 3, "EEPROM: CS=%u SK=%u DI=%u DO=%u, tick = %u\n", + eecs, eesk, eedi, nmc93cxx_eeprom_read(dev), dev->write_tick); + + if (dev->cs_state != eecs) { + dev->cs_state = eecs; + + /* Remember the rising edge tick so we don't process CLK signals at the same time */ + if (eecs) { + dev->last_cs_rising_edge_tick = dev->write_tick; } + + nmc93cxx_eeprom_handle_event(dev, eecs ? EVENT_CS_RISING_EDGE : EVENT_CS_FALLING_EDGE); + } + + dev->di_state = eedi; + + if (dev->clk_state != eesk) { + dev->clk_state = eesk; + nmc93cxx_eeprom_handle_event(dev, eesk ? EVENT_CLK_RISING_EDGE : EVENT_CLK_FALLING_EDGE); } - /* Save status of EEPROM. */ - eeprom->dev.count = tick; - eeprom->dev.oldena = eecs; - eeprom->dev.oldclk = eesk; - eeprom->dev.out = eedo; - eeprom->dev.address = address; - eeprom->dev.opcode = command; } -uint16_t -nmc93cxx_eeprom_read(nmc93cxx_eeprom_t *eeprom) +bool +nmc93cxx_eeprom_read(nmc93cxx_eeprom_t *dev) { - /* Return status of pin DO (0 or 1). */ - return eeprom->dev.out; + assert(dev != NULL); + + if (dev->state == STATE_WAIT_FOR_START_BIT) { + /* Read the state of the READY/BUSY line */ + return !dev->is_busy; + } else if (dev->state == STATE_READING_DATA) { + /* Read the current output bit */ + return ((dev->shift_register & 0x80000000) != 0); + } + + /* The DO pin is tristated */ + return true; } static void nmc93cxx_eeprom_close(void *priv) { - nmc93cxx_eeprom_t *eeprom = (nmc93cxx_eeprom_t *) priv; - FILE *fp = nvr_fopen(eeprom->filename, "wb"); + nmc93cxx_eeprom_t *dev = priv; + FILE *fp = nvr_fopen(dev->filename, "wb"); if (fp) { - fwrite(eeprom->dev.data, 2, eeprom->size, fp); + fwrite(dev->array_data, dev->data_bits / 8, dev->cells, fp); fclose(fp); } - free(priv); + log_close(dev->log); + free(dev); } -uint16_t * -nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *eeprom) +const uint16_t * +nmc93cxx_eeprom_data(nmc93cxx_eeprom_t *dev) { + assert(dev != NULL); + /* Get EEPROM data array. */ - return &eeprom->dev.data[0]; + return &dev->array_data[0]; } const device_t nmc93cxx_device = { diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index decb23d028..9799053859 100644 --- a/src/network/net_ne2000.c +++ b/src/network/net_ne2000.c @@ -182,7 +182,7 @@ nic_config_reset(void *priv) { nic_t *dev = (nic_t *) priv; - uint8_t *data = (uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); + const uint8_t *data = (const uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); dev->config1 = (data[0x00] & 0x7f) | 0x80; dev->config2 = (data[0x01] & 0xdf); @@ -425,7 +425,7 @@ page3_read(nic_t *dev, uint32_t off, UNUSED(unsigned int len)) case 0xd: /* CONFIG4 */ if (dev->board == NE2K_RTL8019AS_PNP) { - uint8_t *data = (uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); + const uint8_t *data = (const uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); ret = data[0x03]; } break; @@ -464,7 +464,7 @@ page3_write(nic_t *dev, uint32_t off, uint32_t val, UNUSED(unsigned len)) if ((val & 0xc0) == 0x80) nmc93cxx_eeprom_write(dev->eeprom, !!(val & 0x08), !!(val & 0x04), !!(val & 0x02)); else if ((val & 0xc0) == 0x40) { - uint8_t *data = (uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); + const uint8_t *data = (const uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); dev->config1 = (data[0x00] & 0x7f) | 0x80; dev->config2 = (data[0x01] & 0xdf); @@ -1391,18 +1391,15 @@ nic_init(const device_t *info) nmc93cxx_eeprom_params_t params; char filename[1024] = { 0 }; - params.nwords = 64; - params.default_content = (uint16_t *) dev->eeprom_data; + params.type = NMC_93C46_x16_64; + params.default_content = dev->eeprom_data; params.filename = filename; int inst = device_get_instance(); snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, inst); dev->eeprom = device_add_inst_params(&nmc93cxx_device, inst, ¶ms); - if (dev->eeprom == NULL) { - free(dev); - return NULL; - } + if (info->local == NE2K_RTL8019AS_PNP) { - uint8_t *data = (uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); + const uint8_t *data = (const uint8_t *) nmc93cxx_eeprom_data(dev->eeprom); dev->config1 = (data[0x00] & 0x7f) | 0x80; dev->config2 = (data[0x01] & 0xdf); diff --git a/src/network/net_rtl8139.c b/src/network/net_rtl8139.c index 5c50f088cc..0daf25a6a3 100644 --- a/src/network/net_rtl8139.c +++ b/src/network/net_rtl8139.c @@ -3286,15 +3286,11 @@ nic_init(const device_t *info) for (uint32_t i = 0; i < 6; i++) s->phys[MAC0 + i] = mac_bytes[i]; - params.nwords = 64; - params.default_content = (uint16_t *) s->eeprom_data; + params.type = NMC_93C46_x16_64; + params.default_content = s->eeprom_data; params.filename = filename; snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, s->inst); s->eeprom = device_add_inst_params(&nmc93cxx_device, s->inst, ¶ms); - if (s->eeprom == NULL) { - free(s); - return NULL; - } s->nic = network_attach(s, (uint8_t *) &s->phys[MAC0], rtl8139_do_receive, rtl8139_set_link_status); timer_add(&s->timer, rtl8139_timer, s, 0); diff --git a/src/network/net_tulip.c b/src/network/net_tulip.c index e95810cfa2..b5219cf237 100644 --- a/src/network/net_tulip.c +++ b/src/network/net_tulip.c @@ -1642,16 +1642,12 @@ nic_init(const device_t *info) } if (info->local != 3) { - params.nwords = 64; - params.default_content = (uint16_t *) s->eeprom_data; + params.type = NMC_93C46_x16_64; + params.default_content = s->eeprom_data; params.filename = filename; int inst = device_get_instance(); snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, inst); s->eeprom = device_add_inst_params(&nmc93cxx_device, inst, ¶ms); - if (s->eeprom == NULL) { - free(s); - return NULL; - } } s->tulip_pci_bar[0].addr_regs[0] = 1; diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index 51aea3f46d..327d35cbb1 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -2091,19 +2092,17 @@ esp_pci_write(UNUSED(int func), int addr, UNUSED(int len), uint8_t val, void *pr { esp_t *dev = (esp_t *) priv; uint8_t valxor; - int eesk; - int eedi; esp_log("%04X:%08X: ESP PCI: Write value %02X to register %02X\n", CS, cpu_state.pc, val, addr); if (!dev->local) { if ((addr >= 0x80) && (addr <= 0xFF)) { if (addr == 0x80) { - eesk = val & 0x80 ? 1 : 0; - eedi = val & 0x40 ? 1 : 0; - nmc93cxx_eeprom_write(dev->eeprom, 1, eesk, eedi); + bool eesk = !!(val & 0x80); + bool eedi = !!(val & 0x40); + nmc93cxx_eeprom_write(dev->eeprom, true, eesk, eedi); } else if (addr == 0xc0) - nmc93cxx_eeprom_write(dev->eeprom, 0, 0, 0); + nmc93cxx_eeprom_write(dev->eeprom, false, false, false); // esp_log("ESP PCI: Write value %02X to register %02X\n", val, addr); return; } @@ -2300,8 +2299,8 @@ dc390_init(const device_t *info) dev->eeprom_data[EE_CHKSUM1] = checksum & 0xff; dev->eeprom_data[EE_CHKSUM2] = checksum >> 8; - params.nwords = 64; - params.default_content = (uint16_t *) dev->eeprom_data; + params.type = NMC_93C46_x16_64; + params.default_content = dev->eeprom_data; params.filename = filename; snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, dev->eeprom_inst); dev->eeprom = device_add_inst_params(&nmc93cxx_device, dev->eeprom_inst, ¶ms); diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 3965391cb9..37ade5ad1a 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -12237,15 +12237,11 @@ s3_init(const device_t *info) checksum = s3_calc_crc16(64, s3->eeprom_data); s3->eeprom_data[0x00] = checksum; - params.nwords = 64; + params.type = NMC_93C46_x16_64; params.default_content = s3->eeprom_data; params.filename = filename; snprintf(filename, sizeof(filename), "nmc93cxx_eeprom_%s_%d.nvr", info->internal_name, s3->eeprom_inst); s3->eeprom = device_add_inst_params(&nmc93cxx_device, s3->eeprom_inst, ¶ms); - if (s3->eeprom == NULL) { - free(s3); - return NULL; - } } s3->accel.multifunc[0xd] = 0xd000; From e6935b78ff6c9a792fd4fbc5de64b17e0fff572b Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Jan 2026 06:34:05 +0100 Subject: [PATCH 44/58] VFIO: Fix a compile-breaking error accidentally introduced earlier today. --- src/device/vfio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/device/vfio.c b/src/device/vfio.c index 776ded002a..6ffb62c86d 100644 --- a/src/device/vfio.c +++ b/src/device/vfio.c @@ -2569,7 +2569,7 @@ vfio_dev_prereset(vfio_device_t *dev) dev->can_flr_reset = (dev->pcie_cap && (vfio_config_readb(0, dev->pcie_cap + 7, 1, dev) & 0x10)) || (dev->af_cap && (vfio_config_readb(0, dev->af_cap + 3, 1, dev) & 0x02)); /* Disable bus master, BARs, expansion ROM and VGA regions; also enable INTx. */ - vfio_config_writew(0, 0x04, vfio_config_readw(0, 0x04, 2, dev) & ~0x0407, dev); + vfio_config_writew(0, 0x04, 2, vfio_config_readw(0, 0x04, 2, dev) & ~0x0407, dev); } static void From 2df173592b382fd61258aa7291fc762140c58681 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Jan 2026 06:53:28 +0100 Subject: [PATCH 45/58] NMC93cXX: Fix two warnings and a security alert. --- src/mem/nmc93cxx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/mem/nmc93cxx.c b/src/mem/nmc93cxx.c index c998fb825c..bdbc46c92f 100644 --- a/src/mem/nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -130,9 +130,6 @@ nmc93cxx_eeprom_log(nmc93cxx_eeprom_t *dev, int lvl, const char *fmt, ...) va_end(ap); } } -#else -# define nmc93cxx_eeprom_log(dev, lvl, fmt, ...) -#endif #define MAKE_CASE(x) case x: return #x; static char* @@ -149,7 +146,7 @@ nmc93cxx_eeprom_state_to_name(EepromState state) } } -static char* +static char * nmc93cxx_eeprom_cmd_to_name(EepromCommand command) { switch (command) { @@ -167,6 +164,9 @@ nmc93cxx_eeprom_cmd_to_name(EepromCommand command) } } #undef MAKE_CASE +#else +# define nmc93cxx_eeprom_log(dev, lvl, fmt, ...) +#endif static void nmc93cxx_eeprom_set_state(nmc93cxx_eeprom_t *dev, EepromState state) @@ -305,11 +305,11 @@ nmc93cxx_eeprom_init(const device_t *info) snprintf(dev->filename, sizeof(dev->filename), "%s", params_details->filename); FILE *fp = nvr_fopen(dev->filename, "rb"); if (fp) { - fill_default = !fread(dev->array_data, dev->data_bits / 8, dev->cells, fp); + fill_default = !fread(dev->array_data, (size_t) dev->data_bits / 8, dev->cells, fp); fclose(fp); } if (fill_default && params_details->default_content) { - memcpy(dev->array_data, params_details->default_content, dev->cells * (dev->data_bits / 8)); + memcpy(dev->array_data, params_details->default_content, (size_t) dev->cells * ((size_t) dev->data_bits / 8)); } /* Compute address bits */ From abfb3a92ceea442f03f08ca711f84c9347bb9ea8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Jan 2026 07:25:14 +0100 Subject: [PATCH 46/58] CL-GD 54xx: Fix the conditions for thunking to the (S)VGA read/write functions, fixes the Diamond SpeedStar 64 (5434) drivers, E-Ten Chinese System verified to still work. --- src/video/vid_cl54xx.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/video/vid_cl54xx.c b/src/video/vid_cl54xx.c index 089b2ec7ff..7979758ef2 100644 --- a/src/video/vid_cl54xx.c +++ b/src/video/vid_cl54xx.c @@ -2288,7 +2288,7 @@ gd54xx_write(uint32_t addr, uint8_t val, void *priv) xga_write_test(addr, val, svga); - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_write(addr, val, svga); return; } @@ -2318,7 +2318,7 @@ gd54xx_writew(uint32_t addr, uint16_t val, void *priv) xga_write_test(addr, val, svga); xga_write_test(addr + 1, val >> 8, svga); - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writew(addr, val, svga); return; } @@ -2357,7 +2357,7 @@ gd54xx_writel(uint32_t addr, uint32_t val, void *priv) xga_write_test(addr + 2, val >> 16, svga); xga_write_test(addr + 3, val >> 24, svga); - if ((svga->seqregs[0x07] & 0x01) == 0) { + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) { svga_writel(addr, val, svga); return; } @@ -2914,7 +2914,7 @@ gd54xx_read(uint32_t addr, void *priv) svga_t *svga = (svga_t *) priv; gd54xx_t *gd54xx = (gd54xx_t *) svga->local; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_read(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && @@ -2935,7 +2935,7 @@ gd54xx_readw(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) svga->local; uint16_t ret; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_readw(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && @@ -2960,7 +2960,7 @@ gd54xx_readl(uint32_t addr, void *priv) gd54xx_t *gd54xx = (gd54xx_t *) svga->local; uint32_t ret; - if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA) || !(svga->gdcreg[5] & 0x40)) + if (!(svga->seqregs[0x07] & CIRRUS_SR7_BPP_SVGA)) return svga_readl(addr, svga); if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && From 7de75efd08caa6b7eff6aba0ecf9556fb61a5443 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 25 Jan 2026 11:08:55 +0100 Subject: [PATCH 47/58] Flash chips: Make sure they have the ROM wait states, should make POST times less unrealistically fast. --- src/mem/catalyst_flash.c | 6 +++--- src/mem/intel_flash.c | 6 +++--- src/mem/sst_flash.c | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mem/catalyst_flash.c b/src/mem/catalyst_flash.c index da9bfc2492..bed0384af7 100644 --- a/src/mem/catalyst_flash.c +++ b/src/mem/catalyst_flash.c @@ -177,16 +177,16 @@ catalyst_flash_add_mappings(flash_t *dev) mem_mapping_add(&dev->mapping, 0xe0000, 0x20000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); mem_mapping_add(&(dev->mapping_h[0]), 0xfffc0000, 0x20000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); mem_mapping_add(&(dev->mapping_h[1]), 0xfffe0000, 0x20000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); } static void diff --git a/src/mem/intel_flash.c b/src/mem/intel_flash.c index 50e8016ce5..266bd78351 100644 --- a/src/mem/intel_flash.c +++ b/src/mem/intel_flash.c @@ -320,16 +320,16 @@ intel_flash_add_mappings(flash_t *dev) mem_mapping_add(&(dev->mapping[i]), base, 0x10000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); } mem_mapping_add(&(dev->mapping_h[i]), (base | 0xfff00000) - sub, 0x10000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); mem_mapping_add(&(dev->mapping_h[i + max]), (base | 0xfff00000), 0x10000, flash_read, flash_readw, flash_readl, flash_write, flash_writew, flash_writel, - dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); } } diff --git a/src/mem/sst_flash.c b/src/mem/sst_flash.c index 024bcf6a57..656ed225b3 100644 --- a/src/mem/sst_flash.c +++ b/src/mem/sst_flash.c @@ -485,18 +485,18 @@ sst_add_mappings(sst_t *dev) mem_mapping_add(&(dev->mapping[i]), base, 0x10000, sst_read, sst_readw, sst_readl, sst_write, NULL, NULL, - dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); } if (is6117) { mem_mapping_add(&(dev->mapping_h[i]), (base | 0x3f00000), 0x10000, sst_read, sst_readw, sst_readl, sst_write, NULL, NULL, - dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); } else { mem_mapping_add(&(dev->mapping_h[i]), (base | (cpu_16bitbus ? 0xf00000 : 0xfff00000)), 0x10000, sst_read, sst_readw, sst_readl, sst_write, NULL, NULL, - dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS, (void *) dev); + dev->array + fbase, MEM_MAPPING_EXTERNAL | MEM_MAPPING_ROM | MEM_MAPPING_ROMCS | MEM_MAPPING_ROM_WS, (void *) dev); } } } From a3fbb33e1078baf31ec9f79d601f4bab4ee78237 Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 26 Jan 2026 09:40:24 +0100 Subject: [PATCH 48/58] Generic PCL Printer: Set language version to PCL 5C (PCL 5E is still supported as PCL 5C is a superset of it) and apply a few fixes, including no longer incorrectly processing the 1B 0E escape (it appears that's actually used as part of PCL 5C), fixes the HP Color LaserJet drivers when outputting to PDF. --- src/printer/prt_ps.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index adf57a5237..bb153723ce 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -156,7 +156,7 @@ convert_to_pdf(ps_t *dev) gsargv[arg++] = "-sDEVICE=pdfwrite"; if (dev->pcl) { gsargv[arg++] = "-LPCL"; - gsargv[arg++] = "-lPCL5E"; + gsargv[arg++] = "-lPCL5C"; } gsargv[arg++] = "-q"; gsargv[arg++] = "-o"; @@ -299,11 +299,14 @@ process_data(ps_t *dev) dev->pjl = false; else if (!memcmp(&(dev->buffer[dev->pjl_command_start]), "@PJL ENTER LANGUAGE=POSTSCRIPT", 0x1e)) fatal("Printing PostScript using the PCL printer is not (yet) supported!\n"); + dev->buffer[dev->buffer_pos] = 0x00; dev->buffer_pos = dev->pjl_command_start; } else if (!dev->pjl_command && (dev->buffer_pos >= 0x05) && !memcmp(&(dev->buffer[dev->buffer_pos - 0x5]), "@PJL ", 0x05)) { dev->pjl_command = true; dev->pjl_command_start = dev->buffer_pos - 0x05; - } + } else if (!dev->pjl_command && (dev->data == 0x1b)) + /* The universal exit code is also valid in PJL. */ + dev->pcl_escape = 1; dev->buffer[dev->buffer_pos] = 0; return; @@ -312,15 +315,6 @@ process_data(ps_t *dev) else switch (dev->pcl_escape) { case 1: dev->pcl_escape = (dev->data == 0x25) ? 2 : 0; - if (dev->data == 0x0e) { - dev->buffer[dev->buffer_pos++] = dev->data; - dev->buffer[dev->buffer_pos] = 0; - - if (dev->buffer_pos > 2) - write_buffer(dev, true); - - return; - } break; case 2: dev->pcl_escape = (dev->data == 0x2d) ? 3 : 0; @@ -342,8 +336,19 @@ process_data(ps_t *dev) break; case 8: dev->pcl_escape = 0; - if (dev->data == 0x58) + if (dev->data == 0x58) { dev->pjl = true; + + dev->buffer[dev->buffer_pos++] = dev->data; + dev->buffer[dev->buffer_pos] = 0; + + if (dev->pjl) + /* Wipe the slate clean so that there won't be a bogus empty page output to PDF. */ + dev->pending = false; + else if (dev->buffer_pos > 9) + write_buffer(dev, true); + return; + } break; } } else if ((dev->data < 0x20) || (dev->data == 0x7f)) { From 9c27adeef5593183524f435244cdf8f058e452b5 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Mon, 26 Jan 2026 18:02:23 +0100 Subject: [PATCH 49/58] Some clean up on 8514/A 1. Remove more hacks usually placed for stuff to make them work, now stuff works per manual. 2. Pixtrans reads are no longer written in the accelerator function per manual. Warning: I still don't know how to properly fix the 8514/A bug on win2.x paint/pbrush, the commands are fine as well as the rop/mixes and the coordinates as well, I need help for this. --- src/video/vid_8514a.c | 906 +++++++++++++++++++++--------------------- 1 file changed, 443 insertions(+), 463 deletions(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index ca7e182b00..872743b72e 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -261,8 +261,8 @@ void ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, int len) { ibm8514_t *dev = (ibm8514_t *) svga->dev8514; - uint8_t nibble = 0; - uint32_t pixelxfer = 0; + uint8_t nibble = 0x0000; + uint32_t pixelxfer = 0x00000000; uint32_t monoxfer = 0xffffffff; int pixcnt = 0; int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; @@ -289,8 +289,23 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in val = (val >> 8) | (val << 8); } if ((cmd <= 2) || (cmd == 4) || (cmd == 6)) { - if ((dev->accel.cmd & 0x08) && (cmd >= 1)) { - monoxfer = val; + if (dev->accel.cmd & 0x08) { + if (val & 0x02) + nibble |= 0x08; + if (val & 0x04) + nibble |= 0x04; + if (val & 0x08) + nibble |= 0x02; + if (val & 0x10) + nibble |= 0x01; + if (val & 0x200) + nibble |= 0x80; + if (val & 0x400) + nibble |= 0x40; + if (val & 0x800) + nibble |= 0x20; + if (val & 0x1000) + nibble |= 0x10; } else { if (val & 0x02) nibble |= 0x80; @@ -308,9 +323,8 @@ ibm8514_accel_out_pixtrans(svga_t *svga, UNUSED(uint16_t port), uint32_t val, in nibble |= 0x02; if (val & 0x1000) nibble |= 0x01; - - monoxfer = nibble; } + monoxfer = nibble; } else monoxfer = val; } else @@ -545,7 +559,7 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) if (dev->accel.cmd & 0x100) dev->accel.cmd_back = 0; - ibm8514_log("8514/A CMD=%04x, frgd color=%04x, frgdmix=%02x, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.frgd_color, dev->accel.frgd_mix, dev->accel.multifunc[0x0a]); + ibm8514_log("8514A CMDflags=%04x, frgd color=%04x, frgdmix=%02x, pixcntl=%02x.\n", dev->accel.cmd, dev->accel.frgd_color, dev->accel.frgd_mix, dev->accel.multifunc[0x0a]); ibm8514_accel_start(-1, 0, -1, 0, svga, len); } break; @@ -894,9 +908,6 @@ ibm8514_accel_in_fifo(svga_t *svga, uint16_t port, int len) } ibm8514_accel_out_pixtrans(svga, port, (temp >> 8) & 0xff, len); } else { - if (dev->accel.input3) - temp = 0xffff; - ibm8514_accel_out_pixtrans(svga, port, temp, len); } } @@ -981,6 +992,10 @@ ibm8514_accel_in(uint16_t port, svga_t *svga) dev->data_available2 = 0; temp |= INT_FIFO_EMP; } + if (!dev->fifo_idx) { + if (dev->accel.cmd_back) + temp |= 0x800; + } temp |= (dev->subsys_stat | (dev->vram_512k_8514 ? 0x00 : 0x80)); temp |= 0x20; } @@ -1070,6 +1085,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat uint16_t bkgd_color = dev->accel.bkgd_color; uint32_t old_mix_dat; int and3 = dev->accel.cur_x & 3; + int and3_blt = dev->accel.destx & 3; int poly_src; if (!dev->bpp) { @@ -1229,7 +1245,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (dev->accel.ssv_draw) { if ((dev->accel.cmd & 0x04) && dev->accel.ssv_len) { WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); @@ -1300,42 +1315,44 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { dev->subsys_stat |= INT_GE_BSY; - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; + if (ibm8514_cpu_src(svga) || !cpu_input) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; - default: - break; - } + default: + break; + } - READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if (dev->accel.ssv_draw) { - if ((dev->accel.cmd & 0x04) && dev->accel.ssv_len) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 0x04)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + if (dev->accel.ssv_draw) { + if ((dev->accel.cmd & 0x04) && dev->accel.ssv_len) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } } } } @@ -1397,12 +1414,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat case 1: /*Draw line*/ if (!cpu_input) { - dev->accel.init_cx = 0; - dev->accel.input3 = 0; dev->accel.output = 0; - dev->accel.output3 = 0; dev->accel.x_count = 0; - dev->accel.xx_count = 0; dev->accel.cx = dev->accel.cur_x; if (dev->accel.cur_x >= 0x600) @@ -1414,19 +1427,41 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sy = dev->accel.maj_axis_pcnt; - ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x, and3=%d, sy=%d.\n", - cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix, and3, dev->accel.sy); + ibm8514_log("CMD=%d, full=%04x, curx=%d, cury=%d, pixcntl=%x, frgdsel=%d, bkgdsel=%d, frgdmix=%02x, bkgdmix=%02x, and3=%d, sy=%d, polygon=%02x.\n", + cmd, dev->accel.cmd, dev->accel.cx, dev->accel.cy, pixcntl, frgd_mix, bkgd_mix, dev->accel.frgd_mix, dev->accel.bkgd_mix, and3, dev->accel.sy, dev->accel.multifunc[0x0a] & 0x06); ibm8514_log("Line Draw 8514/A CMD=%04x, frgdmix=%d, bkgdmix=%d, c(%d,%d), pixcntl=%d, sy=%d, polyfill=%x, selfrmix=%02x, selbkmix=%02x, bkgdcol=%02x, frgdcol=%02x, clipt=%d, clipb=%d.\n", dev->accel.cmd, frgd_mix, bkgd_mix, dev->accel.cx, dev->accel.cy, pixcntl, dev->accel.sy, dev->accel.multifunc[0x0a] & 6, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, bkgd_color, frgd_color, dev->accel.clip_top, clip_b); if (ibm8514_cpu_src(svga)) { if (dev->accel.cmd & 0x02) { if (!(dev->accel.cmd & 0x1000)) { if (dev->accel.cmd & 0x08) { - if (dev->accel.cmd == 0x211b) { - dev->accel.x_count = dev->accel.cx - (and3 + 3); - dev->accel.sy += (and3 + 3); - } else + if (and3) { + dev->accel.sy += and3; dev->accel.output = 1; + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx -= and3; + break; + case 0x20: + dev->accel.cx -= and3; + break; + case 0x60: + dev->accel.cx += and3; + break; + case 0x80: + dev->accel.cx += and3; + break; + case 0xa0: + dev->accel.cx += and3; + break; + case 0xe0: + dev->accel.cx -= and3; + break; + + default: + break; + } + } } } } @@ -1436,15 +1471,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->data_available2 = 0; return; /*Wait for data from CPU*/ } else if (ibm8514_cpu_dest(svga)) { - if (dev->accel.cmd & 0x02) { - if (!(dev->accel.cmd & 0x1000)) { - if (dev->accel.cmd & 0x08) { - if ((frgd_mix == 3) && (bkgd_mix == 3) && (pixcntl == 0) && - ((dev->accel.multifunc[0x0a] & 0x06) == 0x04) && (dev->accel.frgd_mix != 0x07)) /*Kinda of a workaround for fill brushes on 8514/A using Windows 2.x*/ - dev->accel.input3 = 1; - } - } - } dev->force_busy = 1; dev->force_busy2 = 1; dev->data_available = 1; @@ -1454,239 +1480,253 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } if (dev->accel.cmd & 0x08) { /*Vector Line*/ - if (ibm8514_cpu_dest(svga) && cpu_input && (dev->accel.cmd & 0x02)) - count >>= 1; + if (ibm8514_cpu_dest(svga)) { + if (dev->accel.cmd & 0x02) + count >>= 1; - if (dev->accel.cmd == 0x211b) { - if (and3 >= 2) { - if (dev->accel.sy < (count << 1)) - count <<= 1; - } - } - if (dev->accel.cmd & 0x1000) - ibm8514_log("Vector Line %d: full=%04x, odd=%d, c(%d,%d), frgdmix=%d, bkgdmix=%d, xcount=%d, and3=%d, len(%d,%d), CURX=%d, Width=%d, pixcntl=%d, mix_dat=%08x, count=%d, cpu_data=%08x, cpu_input=%d.\n", cmd, dev->accel.cmd, dev->accel.input, dev->accel.cx, dev->accel.cy, frgd_mix, bkgd_mix, dev->accel.x_count, and3, dev->accel.sx, dev->accel.sy, dev->accel.cur_x, dev->accel.maj_axis_pcnt, pixcntl, mix_dat, count, cpu_dat, cpu_input); + if ((dev->accel.multifunc[0x0a] & 0x06) == 0x04) { + ibm8514_log("Destination Vector Line CNT=%d.\n", count); + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { + dev->subsys_stat |= INT_GE_BSY; + } else + ibm8514_log("Scissor out of bounds.\n"); - while (count-- && (dev->accel.sy >= 0)) { - ibm8514_log("CurrentX=%d, CurrentY=%d, Count=%d.\n", dev->accel.cx, dev->accel.cy, count); - if ((dev->accel.cx >= clip_l) && - (dev->accel.cx <= clip_r) && - (dev->accel.cy >= clip_t) && - (dev->accel.cy <= clip_b)) { - dev->subsys_stat |= INT_GE_BSY; - if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ((dev->accel.cy * dev->pitch) + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } + if (!dev->accel.sy) { + dev->force_busy = 0; + dev->force_busy2 = 0; + dev->fifo_idx = 0; + dev->accel.cmd_back = 1; + break; + } - if (ibm8514_cpu_dest(svga)) { - READ((dev->accel.cy * dev->pitch) + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else { - if (dev->accel.cmd == 0x211b) { - if (dev->accel.x_count != dev->accel.cx) { - dev->accel.output3 = 1; - } else { - dev->accel.output3 = 0; - } + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx++; + break; + case 0x20: + dev->accel.cx++; + dev->accel.cy--; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cx--; + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx--; + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cx++; + dev->accel.cy++; + break; - if (dev->accel.output3 == 1) - goto skip_vector_line_write; + default: + break; } - if (dev->accel.output) { - switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; + dev->accel.sy--; + } + } else { + while (count-- && (dev->accel.sy >= 0)) { + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { + dev->subsys_stat |= INT_GE_BSY; + } - default: - break; - } - } else { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; + if (!dev->accel.sy) { + dev->force_busy = 0; + dev->force_busy2 = 0; + dev->fifo_idx = 0; + dev->accel.cmd_back = 1; + break; + } - default: - break; - } + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx++; + break; + case 0x20: + dev->accel.cx++; + dev->accel.cy--; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cx--; + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx--; + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cx++; + dev->accel.cy++; + break; + + default: + break; } + + dev->accel.sy--; } + } + } else { + if (ibm8514_cpu_src(svga)) { + if ((dev->accel.cmd & 0x02) && (pixcntl != 2)) + count >>= 1; + } - READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + while (count-- && (dev->accel.sy >= 0)) { + ibm8514_log("CurrentX=%d, CurrentY=%d, Count=%d.\n", dev->accel.cx, dev->accel.cy, count); + if ((dev->accel.cx >= clip_l) && + (dev->accel.cx <= clip_r) && + (dev->accel.cy >= clip_t) && + (dev->accel.cy <= clip_b)) { + dev->subsys_stat |= INT_GE_BSY; + switch ((mix_dat & ((dev->accel.cmd & 0x02) ? 0x01 : mix_mask)) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - if (dev->accel.output) { - MIX(mix_dat & 0x01, dest_dat, src_dat); - } else { - MIX(mix_dat & mix_mask, dest_dat, src_dat); + default: + break; } - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 0x02) && ibm8514_cpu_src(svga)) { - if ((dev->accel.cmd & 0x04) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 0x04)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } - } else { - if (ibm8514_cpu_src(svga) || !cpu_input) { - if ((dev->accel.cmd & 0x04) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 0x04)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + + READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & ((dev->accel.cmd & 0x02) ? 0x01 : mix_mask), dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + if ((dev->accel.cmd & 0x02) && ibm8514_cpu_src(svga)) { + if (!(dev->accel.cmd & 0x1000)) { + if (dev->accel.x_count >= and3) { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } + } + } else { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } } - } else if (dev->accel.input3) { - if ((dev->accel.cmd & 0x04) && dev->accel.sy) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat ? dest_dat : 0xff); - } else if (!(dev->accel.cmd & 0x04)) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat ? dest_dat : 0xff); + } else { + if (ibm8514_cpu_src(svga) || !cpu_input) { + if ((dev->accel.cmd & 0x04) && dev->accel.sy) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } } } } } - } - - if (!dev->accel.sy) { - if (cpu_input) { - dev->force_busy = 0; - dev->force_busy2 = 0; - } - dev->fifo_idx = 0; - dev->accel.cmd_back = 1; - if (!cpu_input) { - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; - } - break; - } - - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.cx++; - break; - case 0x20: - dev->accel.cx++; - if (!dev->accel.output3) - dev->accel.cy--; - break; - case 0x40: - if (!dev->accel.output3) - dev->accel.cy--; - break; - case 0x60: - dev->accel.cx--; - if (!dev->accel.output3) - dev->accel.cy--; - break; - case 0x80: - dev->accel.cx--; - break; - case 0xa0: - dev->accel.cx--; - if (!dev->accel.output3) - dev->accel.cy++; - break; - case 0xc0: - if (!dev->accel.output3) - dev->accel.cy++; - break; - case 0xe0: - dev->accel.cx++; - if (!dev->accel.output3) - dev->accel.cy++; + if (!dev->accel.sy) { + if (cpu_input) { + dev->force_busy = 0; + dev->force_busy2 = 0; + } + dev->fifo_idx = 0; + dev->accel.cmd_back = 1; + if (!cpu_input) { + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; + } break; + } - default: - break; - } + if (dev->bpp) + cpu_dat >>= 16; + else + cpu_dat >>= 8; -skip_vector_line_write: - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.x_count++; - break; - case 0x20: - dev->accel.x_count++; - if (dev->accel.output3) + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx++; + break; + case 0x20: + dev->accel.cx++; dev->accel.cy--; - break; - case 0x40: - if (dev->accel.output3) + break; + case 0x40: dev->accel.cy--; - break; - case 0x60: - dev->accel.x_count--; - if (dev->accel.output3) + break; + case 0x60: + dev->accel.cx--; dev->accel.cy--; - break; - case 0x80: - dev->accel.x_count--; - break; - case 0xa0: - dev->accel.x_count--; - if (dev->accel.output3) + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx--; dev->accel.cy++; - break; - case 0xc0: - if (dev->accel.output3) + break; + case 0xc0: dev->accel.cy++; - break; - case 0xe0: - dev->accel.x_count++; - if (dev->accel.output3) + break; + case 0xe0: + dev->accel.cx++; dev->accel.cy++; - break; + break; - default: - break; - } + default: + break; + } - if (dev->accel.output) - mix_dat >>= 1; - else { - mix_dat <<= 1; - mix_dat |= 1; + if (dev->accel.cmd & 0x02) + mix_dat >>= 1; + else { + mix_dat <<= 1; + mix_dat |= 1; + } + dev->accel.sy--; + dev->accel.x_count++; } - - dev->accel.sy--; } - dev->accel.output = 0; } else { /*Bresenham Line*/ if (pixcntl == 1) { dev->accel.temp_cnt = 8; @@ -1912,9 +1952,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!cpu_input) { dev->accel.x_count = 0; dev->accel.output = 0; + dev->accel.output2 = 0; dev->accel.input = 0; dev->accel.input2 = 0; - dev->accel.input3 = 0; dev->accel.odd_in = 0; dev->accel.cx = dev->accel.cur_x; @@ -1941,19 +1981,43 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (ibm8514_cpu_src(svga)) { if (dev->accel.cmd & 0x02) { if (!(dev->accel.cmd & 0x1000)) { - if (dev->accel.cmd & 0x08) { - dev->accel.x_count = dev->accel.cx - (and3 + 3); - dev->accel.sx += (and3 + 3); - } else { - dev->accel.x_count = dev->accel.cx; + if (!(dev->accel.cmd & 0x08)) { if (and3) { if (dev->accel.cmd & 0x20) - dev->accel.x_count -= and3; + dev->accel.cx -= and3; else - dev->accel.x_count += and3; + dev->accel.cx += and3; dev->accel.sx += 8; } + } else { + if (and3) { + dev->accel.sx += and3; + dev->accel.output2 = 1; + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx -= and3; + break; + case 0x20: + dev->accel.cx -= and3; + break; + case 0x60: + dev->accel.cx += and3; + break; + case 0x80: + dev->accel.cx += and3; + break; + case 0xa0: + dev->accel.cx += and3; + break; + case 0xe0: + dev->accel.cx -= and3; + break; + + default: + break; + } + } } } } else { @@ -1982,10 +2046,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sx -= 2; } } - } else { - if ((dev->accel.cmd == 0x41f0) && (frgd_mix == 3) && (bkgd_mix == 3) && - (pixcntl == 0)) - dev->accel.input3 = 1; } } ibm8514_log("INPUT1=%d, INPUT2=%d.\n", dev->accel.input, dev->accel.input2); @@ -2008,7 +2068,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { dev->subsys_stat |= INT_GE_BSY; - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + ibm8514_log("RectRadial: MIXDATA=%08x, mask=%04x, frgdcol=%02x, bkgdcol=%02x, cpudat=%08x.\n", mix_dat, mix_mask, frgd_color, bkgd_color, cpu_dat); + switch ((mix_dat & ((dev->accel.cmd & 0x02) ? 0x01 : mix_mask)) ? frgd_mix : bkgd_mix) { case 0: src_dat = bkgd_color; break; @@ -2036,15 +2097,15 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; - MIX(mix_dat & mix_mask, dest_dat, src_dat); + MIX(mix_dat & ((dev->accel.cmd & 0x02) ? 0x01 : mix_mask), dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 0x02) && (dev->accel.x_count != dev->accel.cx)) - goto skip_vector_rect_write; - - if ((dev->accel.cmd & 0x04) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 0x04)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + if (dev->accel.x_count >= and3) { + if ((dev->accel.cmd & 0x04) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + ibm8514_log("RectFill Radial CX=%d, CY=%d, dstdat=%02x, olddst=%02x, srcdat=%02x.\n", dev->accel.cx, dev->accel.cy, dest_dat, old_dest_dat, src_dat); + } } } } @@ -2073,42 +2134,24 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat break; } -skip_vector_rect_write: - switch (dev->accel.cmd & 0xe0) { - case 0x00: - dev->accel.x_count++; - break; - case 0x20: - dev->accel.x_count++; - break; - case 0x60: - dev->accel.x_count--; - break; - case 0x80: - dev->accel.x_count--; - break; - case 0xa0: - dev->accel.x_count--; - break; - case 0xe0: - dev->accel.x_count++; - break; - - default: - break; - } - if (dev->bpp) cpu_dat >>= 16; else cpu_dat >>= 8; - mix_dat <<= 1; - mix_dat |= 1; - + if (dev->accel.cmd & 0x02) + mix_dat >>= 1; + else { + mix_dat <<= 1; + mix_dat |= 1; + } dev->accel.sx--; + dev->accel.x_count++; if (dev->accel.sx < 0) { dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.x_count = 0; + if (dev->accel.output2) + dev->accel.sx += and3; if (dev->accel.cmd & 0x20) dev->accel.cx -= (dev->accel.sx + 1); @@ -2142,7 +2185,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.dest = dev->accel.ge_offset + (dev->accel.cy * dev->pitch); dev->accel.sy--; - dev->accel.x_count = 0; if (dev->accel.sy < 0) { dev->force_busy = 0; @@ -2166,93 +2208,59 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat (dev->accel.cy >= clip_t) && (dev->accel.cy <= clip_b)) { dev->subsys_stat |= INT_GE_BSY; - if (ibm8514_cpu_dest(svga) && (pixcntl == 0)) { - mix_dat = mix_mask; /* Mix data = forced to foreground register. */ - } else if (ibm8514_cpu_dest(svga) && (pixcntl == 3)) { - /* Mix data = current video memory value. */ - READ(dev->accel.dest + dev->accel.cx, mix_dat); - mix_dat = ((mix_dat & rd_mask) == rd_mask); - mix_dat = mix_dat ? mix_mask : 0; - } - - if (ibm8514_cpu_dest(svga)) { - READ(dev->accel.dest + dev->accel.cx, src_dat); - if (pixcntl == 3) - src_dat = ((src_dat & rd_mask) == rd_mask); - } else { - if (dev->accel.cmd & 0x02) { - switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; - - default: - break; - } - } else { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - src_dat = 0; - break; + if (ibm8514_cpu_src(svga) || !cpu_input) { + switch ((mix_dat & ((dev->accel.cmd & 0x02) ? 0x01 : mix_mask)) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; - default: - break; - } + default: + break; } - } - READ(dev->accel.dest + dev->accel.cx, dest_dat); - - if ((compare_mode == 0) || - ((compare_mode == 0x10) && (dest_dat >= compare)) || - ((compare_mode == 0x18) && (dest_dat < compare)) || - ((compare_mode == 0x20) && (dest_dat != compare)) || - ((compare_mode == 0x28) && (dest_dat == compare)) || - ((compare_mode == 0x30) && (dest_dat <= compare)) || - ((compare_mode == 0x38) && (dest_dat > compare))) { - old_dest_dat = dest_dat; - if (dev->accel.cmd & 0x02) { - MIX(mix_dat & 0x01, dest_dat, src_dat); - if ((dev->accel.x_count != dev->accel.cx) && !(dev->accel.cmd & 0x1000) && and3) - goto skip_nibble_rect_write; + READ(dev->accel.dest + dev->accel.cx, dest_dat); + if ((compare_mode == 0) || + ((compare_mode == 0x10) && (dest_dat >= compare)) || + ((compare_mode == 0x18) && (dest_dat < compare)) || + ((compare_mode == 0x20) && (dest_dat != compare)) || + ((compare_mode == 0x28) && (dest_dat == compare)) || + ((compare_mode == 0x30) && (dest_dat <= compare)) || + ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & ((dev->accel.cmd & 0x02) ? 0x01 : mix_mask), dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 0x04) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 0x04)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } - } else { - if (ibm8514_cpu_dest(svga) && (cmd == 2)) { - if (pixcntl == 3) { - MIX(mix_dat & mix_mask, dest_dat, src_dat); + if (dev->accel.cmd & 0x02) { + if (dev->accel.cmd & 0x1000) { + if ((dev->accel.cmd & 0x04) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } else { + if (dev->accel.x_count >= and3) { + if ((dev->accel.cmd & 0x04) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } + } } } else { - MIX(mix_dat & mix_mask, dest_dat, src_dat); - } - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - if ((dev->accel.cmd & 0x04) && dev->accel.sx) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); - } else if (!(dev->accel.cmd & 0x04)) { - WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + if ((dev->accel.cmd & 0x04) && dev->accel.sx) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 0x04)) { + WRITE(dev->accel.dest + dev->accel.cx, dest_dat); + } } } } @@ -2262,12 +2270,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat else dev->accel.cx--; -skip_nibble_rect_write: - if (dev->accel.cmd & 0x20) - dev->accel.x_count++; - else - dev->accel.x_count--; - if (dev->accel.cmd & 0x02) mix_dat >>= 1; else { @@ -2281,10 +2283,13 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat cpu_dat >>= 8; dev->accel.sx--; + dev->accel.x_count++; if (dev->accel.sx < 0) { dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; + dev->accel.x_count = 0; if (dev->accel.input) dev->accel.odd_in = 1; + if (dev->accel.output || dev->accel.input2) dev->accel.sx -= 2; @@ -2301,7 +2306,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.dest = dev->accel.ge_offset + (dev->accel.cy * dev->pitch); dev->accel.sy--; - dev->accel.x_count = 0; if (dev->accel.sy < 0) { dev->fifo_idx = 0; @@ -2957,12 +2961,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (ibm8514_cpu_src(svga)) { if (dev->accel.cmd & 0x02) { if (!(dev->accel.cmd & 0x1000)) { - dev->accel.x_count = dev->accel.cx; - if (and3) { + if (and3_blt) { if (dev->accel.cmd & 0x20) - dev->accel.x_count -= and3; + dev->accel.dx -= and3_blt; else - dev->accel.x_count += and3; + dev->accel.dx += and3_blt; dev->accel.sx += 8; } @@ -3006,50 +3009,27 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat = mix_dat ? mix_mask : 0x00; } } - if (dev->accel.cmd & 0x02) { - switch ((mix_dat & 0x01) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) - src_dat = ((src_dat & rd_mask) == rd_mask); - } - break; - default: - break; - } - } else { - switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { - case 0: - src_dat = bkgd_color; - break; - case 1: - src_dat = frgd_color; - break; - case 2: - src_dat = cpu_dat; - break; - case 3: - READ(dev->accel.src + dev->accel.cx, src_dat); - if (pixcntl == 3) { - if (dev->accel.cmd & 0x10) - src_dat = ((src_dat & rd_mask) == rd_mask); - } - break; + switch (((mix_dat & (dev->accel.cmd & 0x02) ? 0x01 : mix_mask)) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + READ(dev->accel.src + dev->accel.cx, src_dat); + if (pixcntl == 3) { + if (dev->accel.cmd & 0x10) + src_dat = ((src_dat & rd_mask) == rd_mask); + } + break; - default: - break; - } + default: + break; } READ(dev->accel.dest + dev->accel.dx, dest_dat); @@ -3062,16 +3042,17 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { old_dest_dat = dest_dat; + MIX(mix_dat & ((dev->accel.cmd & 0x02) ? 0x01 : mix_mask), dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); if (dev->accel.cmd & 0x02) { - MIX(mix_dat & 0x01, dest_dat, src_dat); - if ((dev->accel.x_count != dev->accel.cx) && !(dev->accel.cmd & 0x1000) && and3) - goto skip_nibble_bitblt_write; - - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + if (dev->accel.cmd & 0x1000) { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } else { + if (dev->accel.x_count >= and3_blt) { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } } else { - MIX(mix_dat & mix_mask, dest_dat, src_dat); - dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dev->accel.dx, dest_dat); } } @@ -3085,12 +3066,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cx--; } -skip_nibble_bitblt_write: - if (dev->accel.cmd & 0x20) - dev->accel.x_count++; - else - dev->accel.x_count--; - if (dev->accel.cmd & 0x02) mix_dat >>= 1; else { @@ -3104,7 +3079,9 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat cpu_dat >>= 8; dev->accel.sx--; + dev->accel.x_count++; if (dev->accel.sx < 0) { + dev->accel.x_count = 0; dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; if (dev->accel.cmd & 0x20) { @@ -3127,7 +3104,6 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.dest = dev->accel.ge_offset + (dev->accel.dy * dev->pitch); dev->accel.sy--; - dev->accel.x_count = 0; if (dev->accel.sy < 0) { dev->accel.cmd_back = 1; @@ -3358,7 +3334,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } else { - while (count-- && dev->accel.sy >= 0) { + if ((dev->accel.cmd == 0xc073) && (dev->accel.frgd_mix == 0x05) && (frgd_mix == 3)) + ibm8514_log("BitBLT PBRUSH: DX=%d, DY=%d, cl=%d, cr=%d, ct=%d, cb=%d.\n", dev->accel.dx, dev->accel.dy, clip_l, clip_r, clip_t, clip_b); + + while (count-- && (dev->accel.sy >= 0)) { if ((dev->accel.dx >= clip_l) && (dev->accel.dx <= clip_r) && (dev->accel.dy >= clip_t) && @@ -3409,7 +3388,8 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); WRITE(dev->accel.dest + dev->accel.dx, dest_dat); - ibm8514_log("BitBLT DX=%d, DY=%d, data=%02x, old=%02x, src=%02x, frmix=%02x, bkmix=%02x, pixcntl=%d.\n", dev->accel.dx, dev->accel.dy, dest_dat, old_dest_dat, src_dat, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, pixcntl); + if ((dev->accel.cmd == 0xc073) && (dev->accel.frgd_mix == 0x05) && (frgd_mix == 3)) + ibm8514_log("BitBLT CX=%d, CY=%d, DX=%d, DY=%d, data=%02x, old=%02x, src=%02x, frmix=%02x, bkmix=%02x, pixcntl=%d.\n", dev->accel.cx, dev->accel.cy, dev->accel.dx, dev->accel.dy, dest_dat, old_dest_dat, src_dat, dev->accel.frgd_mix & 0x1f, dev->accel.bkgd_mix & 0x1f, pixcntl); } } From 1d854ee2b02ea060cf2aab9fbd3af06c0dfb6662 Mon Sep 17 00:00:00 2001 From: DimMan88 Date: Sun, 25 Jan 2026 16:59:01 +0000 Subject: [PATCH 50/58] Translated using Weblate (Greek) Currently translated at 100.0% (1004 of 1004 strings) Translation: 86Box/86Box Translate-URL: https://weblate.86box.net/projects/86box/86box/el/ --- src/qt/languages/el-GR.po | 68 +++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/src/qt/languages/el-GR.po b/src/qt/languages/el-GR.po index 9243c24fb2..5cb45bded0 100644 --- a/src/qt/languages/el-GR.po +++ b/src/qt/languages/el-GR.po @@ -1,6 +1,6 @@ msgid "" msgstr "" -"PO-Revision-Date: 2026-01-10 12:56+0000\n" +"PO-Revision-Date: 2026-01-26 17:57+0000\n" "Last-Translator: DimMan88 \n" "Language-Team: Greek \n" "Language: el-GR\n" @@ -2919,24 +2919,26 @@ msgstr "Επιτυχής διαγραφή των περιεχομένων NVRAM msgid "An error occurred trying to wipe the NVRAM contents of the virtual machine \"%1\"" msgstr "" +"Ένα σφάλμα προέκυψε κατά την εκκαθάριση των περιεχομένων της NVRAM της " +"εικονικής μηχανής \"%1\"" msgid "%1 VM Manager" -msgstr "" +msgstr "%1 VM Manager" msgid "%n disk(s)" -msgstr "" +msgstr "%n δίσκος(οι)" msgid "Unknown Status" -msgstr "" +msgstr "Άγνωστη Κατάσταση" msgid "No Machines Found!" -msgstr "" +msgstr "Δεν βρέθηκαν μηχανές!" msgid "Check for updates on startup" msgstr "Έλεγχος για ενημερώσεις κατα την εκκίνηση" msgid "Unable to determine release information" -msgstr "" +msgstr "Αδυναμία προσδιορισμού πληροφοριών έκδοσης" msgid "There was an error checking for updates:\n\n%1\n\nPlease try again later." msgstr "" @@ -2947,82 +2949,84 @@ msgstr "" "Παρακαλώ προσπαθήστε ξανά αργότερα." msgid "Update check complete" -msgstr "" +msgstr "Ο έλεγχος ενημερώσεων ολοκληρώθηκε" msgid "stable" -msgstr "" +msgstr "σταθερή" msgid "beta" -msgstr "" +msgstr "δοκιμαστική" msgid "You are running the latest %1 version of 86Box: %2" -msgstr "" +msgstr "Τρέχετε την τελευταία %1 έκδοση του 86Box: %2" msgid "version" -msgstr "" +msgstr "έκδοση" msgid "build" -msgstr "" +msgstr "build" msgid "You are currently running version %1." -msgstr "" +msgstr "Τρέχετε την έκδοση %1." msgid "Version %1 is now available." -msgstr "" +msgstr "Έκδοση %1 είναι διαθέσιμη." msgid "You are currently running build %1." -msgstr "" +msgstr "Τρέχετε το build %1." msgid "Build %1 is now available." -msgstr "" +msgstr "Build %1 είναι τώρα διαθέσιμο." msgid "Would you like to visit the download page?" -msgstr "" +msgstr "Επιθυμείτε να επισκεφθείτε την σελίδα λήψεων;" msgid "Visit download page" -msgstr "" +msgstr "Επίσκεψη σελίδας λήψεων" msgid "Update check" -msgstr "" +msgstr "Έλεγχος ενημερώσεων" msgid "Checking for updates…" msgstr "Έλεγχος για ενημερώσεις…" msgid "86Box Update" -msgstr "" +msgstr "Ενημέρωση 86Box" msgid "Release notes:" -msgstr "" +msgstr "Σημειώσεις έκδοσης:" msgid "%1 Hz" -msgstr "" +msgstr "%1 Hz" msgid "Virtual machine crash" -msgstr "" +msgstr "Σφάλμα εικονικής μηχανής" msgid "The virtual machine \"%1\"'s process has unexpectedly terminated with exit code %2." msgstr "" +"Η διεργασία της εικονικής μηχανής \"%1\" τερματίστηκε απροσδόκητα με κωδικό " +"εξόδου %2." msgid "The system will not be added." -msgstr "" +msgstr "Το σύστημα δεν θα προστεθεί." msgid "&Update mouse every CPU frame" msgstr "&Ανανέωση ποντικιού ανα καρέ CPU" msgid "Hue" -msgstr "" +msgstr "Απόχρωση" msgid "Saturation" -msgstr "" +msgstr "Κορεσμός" msgid "Contrast" -msgstr "" +msgstr "Αντίθεση" msgid "Brightness" -msgstr "" +msgstr "Φωτεινότητα" msgid "Sharpness" -msgstr "" +msgstr "Οξύτητα" msgid "&CGA composite settings…" msgstr "Ρυθμίσεις &CGA composite…" @@ -3073,10 +3077,12 @@ msgid "&Allow recompilation" msgstr "&Να επιτρέπεται ανασύνταξη" msgid "&Fast forward" -msgstr "" +msgstr "&Γρήγορα μπροστά" msgid "Fast forward" -msgstr "" +msgstr "Γρήγορα μπροστά" msgid "To change the system directory, stop all running machines." msgstr "" +"Για να αλλάξετε τον κατάλογο συστήματος, σταματήστε πρώτα όλες τις μηχανές " +"σε λειτουργία." From 9b7b92622bc055d8b4089af8971bb25273531797 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 27 Jan 2026 06:47:08 +0100 Subject: [PATCH 51/58] Restructure LPT devices so that lpt_device_t is now only used internally while the exposed LPT devices are now regular device_t's. --- src/86box.c | 2 + src/device/hasp.c | 32 +++++----- src/device/lpt.c | 110 ++++++++++++++++++++--------------- src/include/86box/lpt.h | 59 +++++++++---------- src/include/86box/network.h | 6 +- src/include/86box/prt_devs.h | 12 ++-- src/network/net_plip.c | 33 +++++------ src/printer/prt_escp.c | 28 ++------- src/printer/prt_ps.c | 62 ++++++++++---------- src/printer/prt_text.c | 27 ++------- src/sound/snd_lpt_dac.c | 60 +++++++++---------- src/sound/snd_lpt_dss.c | 30 +++++----- 12 files changed, 214 insertions(+), 247 deletions(-) diff --git a/src/86box.c b/src/86box.c index 80244dc8b8..24e8be26ab 100644 --- a/src/86box.c +++ b/src/86box.c @@ -1704,6 +1704,8 @@ pc_reset_hard_init(void) ide_hard_reset(); + lpt_ports_reset(); + /* Initialize the actual machine and its basic modules. */ machine_init(); diff --git a/src/device/hasp.c b/src/device/hasp.c index ea8b9b413e..920f482572 100644 --- a/src/device/hasp.c +++ b/src/device/hasp.c @@ -302,13 +302,13 @@ hasp_read_status(void *priv) } static void * -hasp_init(void *lpt, int type) +hasp_init(const device_t *info, int type) { hasp_t *dev = calloc(1, sizeof(hasp_t)); hasp_log("HASP: init(%d)\n", type); - dev->lpt = lpt; + dev->lpt = lpt_attach(info->local & 0xf, hasp_write_data, NULL, NULL, hasp_read_status, NULL, NULL, NULL, dev); dev->type = &hasp_types[type]; dev->status = 0x80; @@ -317,9 +317,9 @@ hasp_init(void *lpt, int type) } static void * -hasp_init_savquest(void *lpt) +hasp_init_savquest(const device_t *info) { - return hasp_init(lpt, HASP_TYPE_SAVQUEST); + return hasp_init(info, HASP_TYPE_SAVQUEST); } static void @@ -332,16 +332,16 @@ hasp_close(void *priv) free(dev); } -const lpt_device_t lpt_hasp_savquest_device = { - .name = "Protection Dongle for Savage Quest", - .internal_name = "dongle_savquest", - .init = hasp_init_savquest, - .close = hasp_close, - .write_data = hasp_write_data, - .write_ctrl = NULL, - .strobe = NULL, - .read_status = hasp_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL +const device_t lpt_hasp_savquest_device = { + .name = "Protection Dongle for Savage Quest", + .internal_name = "dongle_savquest", + .flags = DEVICE_LPT, + .local = 0, + .init = hasp_init_savquest, + .close = hasp_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; diff --git a/src/device/lpt.c b/src/device/lpt.c index f7cc6eda0e..b6ec9f0314 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -34,19 +34,22 @@ lpt_port_t lpt_ports[PARALLEL_MAX]; lpt_device_t lpt_devs[PARALLEL_MAX]; -const lpt_device_t lpt_none_device = { +const device_t lpt_none_device = { .name = "None", .internal_name = "none", + .flags = DEVICE_LPT, + .local = 0, .init = NULL, .close = NULL, - .write_data = NULL, - .write_ctrl = NULL, - .read_status = NULL, - .read_ctrl = NULL + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; static const struct { - const lpt_device_t *device; + const device_t *device; } lpt_devices[] = { // clang-format off { &lpt_none_device }, @@ -83,50 +86,41 @@ lpt_log(const char *fmt, ...) # define lpt_log(fmt, ...) #endif +int +lpt_device_available(int id) +{ + if (lpt_devices[id].device) + return device_available(lpt_devices[id].device); + + return 1; +} + const device_t * lpt_device_getdevice(const int id) { - return (device_t *) lpt_devices[id].device->cfgdevice; + return lpt_devices[id].device; } int lpt_device_has_config(const int id) { - int c = 0; - const device_t *dev = (device_t *) lpt_devices[id].device->cfgdevice; - const device_config_t *config; - if (dev == NULL) - return 0; - - if (dev->config == NULL) + if (lpt_devices[id].device == NULL) return 0; - - config = dev->config; - - while (config->type != CONFIG_END) { - c++; - config++; - } - - return (c > 0) ? 1 : 0; + return device_has_config(lpt_devices[id].device); } const char * lpt_device_get_name(const int id) { if (lpt_devices[id].device == NULL) - return NULL; - + return 0; return lpt_devices[id].device->name; } const char * lpt_device_get_internal_name(const int id) { - if (lpt_devices[id].device == NULL) - return NULL; - - return lpt_devices[id].device->internal_name; + return device_get_internal_name(lpt_devices[id].device); } int @@ -147,29 +141,42 @@ void lpt_devices_init(void) { for (uint8_t i = 0; i < PARALLEL_MAX; i++) { - lpt_t *dev = lpt_devs[i].lpt; - - if (lpt_devices[lpt_ports[i].device].device != NULL) { - memcpy(&(lpt_devs[i]), (lpt_device_t *) lpt_devices[lpt_ports[i].device].device, sizeof(lpt_device_t)); - - if (lpt_devs[i].init) - lpt_devs[i].priv = lpt_devs[i].init(dev); - } else - memset(&(lpt_devs[i]), 0x00, sizeof(lpt_device_t)); + memset(&(lpt_devs[i]), 0x00, sizeof(lpt_device_t)); - lpt_devs[i].lpt = dev; + if ((lpt_devices[lpt_ports[i].device].device != NULL) && + (lpt_devices[lpt_ports[i].device].device != &lpt_none_device)) + device_add_params((device_t *) lpt_devices[lpt_ports[i].device].device, (void *) (uintptr_t) i); } } +void * +lpt_attach(int port, + void (*write_data)(uint8_t val, void *priv), + void (*write_ctrl)(uint8_t val, void *priv), + void (*strobe)(uint8_t old, uint8_t val,void *priv), + uint8_t (*read_status)(void *priv), + uint8_t (*read_ctrl)(void *priv), + void (*epp_write_data)(uint8_t is_addr, uint8_t val, void *priv), + void (*epp_request_read)(uint8_t is_addr, void *priv), + void *priv) +{ + lpt_devs[port].write_data = write_data; + lpt_devs[port].write_ctrl = write_ctrl; + lpt_devs[port].strobe = strobe; + lpt_devs[port].read_status = read_status; + lpt_devs[port].read_ctrl = read_ctrl; + lpt_devs[port].epp_write_data = epp_write_data; + lpt_devs[port].epp_request_read = epp_request_read; + lpt_devs[port].priv = priv; + + return lpt_ports[port].lpt; +} + void lpt_devices_close(void) { - for (uint8_t i = 0; i < PARALLEL_MAX; i++) { - if (lpt_devs[i].close) - lpt_devs[i].close(lpt_devs[i].priv); - + for (uint8_t i = 0; i < PARALLEL_MAX; i++) memset(&(lpt_devs[i]), 0x00, sizeof(lpt_device_t)); - } } static uint8_t @@ -954,10 +961,10 @@ lpt_init(const device_t *info) if (lpt_ports[next_inst].enabled || (info->local & 0xFFF00000)) { lpt_log("Adding parallel port %i...\n", next_inst); - dev->dt = &(lpt_devs[next_inst]); - dev->dt->lpt = dev; + dev->dt = &(lpt_devs[next_inst]); + lpt_ports[next_inst].lpt = dev; - dev->fifo = NULL; + dev->fifo = NULL; memset(&dev->fifo_out_timer, 0x00, sizeof(pc_timer_t)); lpt_port_zero(dev); @@ -1033,7 +1040,14 @@ lpt_standalone_init(void) { while (next_inst < (PARALLEL_MAX - 1)) device_add_inst(&lpt_port_device, next_inst + 1); -}; +} + +void +lpt_ports_reset(void) +{ + for (int i = 0; i < PARALLEL_MAX; i++) + lpt_ports[i].lpt = NULL; +} const device_t lpt_port_device = { .name = "Parallel Port", diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index 61c95094f9..89f7cb5d17 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -18,11 +18,6 @@ #endif typedef struct lpt_device_s { - const char *name; - const char *internal_name; - - void *(*init)(void *lpt); - void (*close)(void *priv); void (*write_data)(uint8_t val, void *priv); void (*write_ctrl)(uint8_t val, void *priv); void (*strobe)(uint8_t old, uint8_t val,void *priv); @@ -31,13 +26,7 @@ typedef struct lpt_device_s { void (*epp_write_data)(uint8_t is_addr, uint8_t val, void *priv); void (*epp_request_read)(uint8_t is_addr, void *priv); - void *priv; - struct lpt_t *lpt; -//#ifdef EMU_DEVICE_H -// struct device_t *cfgdevice; -//#else - void *cfgdevice; -//#endif + void * priv; } lpt_device_t; #ifdef _TIMER_H_ @@ -86,6 +75,8 @@ typedef struct lpt_port_s { uint8_t enabled; int device; + + lpt_t *lpt; } lpt_port_t; extern lpt_port_t lpt_ports[PARALLEL_MAX]; @@ -96,6 +87,22 @@ typedef enum { LPT_STATE_WRITE_FIFO } lpt_state_t; +extern const device_t lpt_dac_device; +extern const device_t lpt_dac_stereo_device; + +extern const device_t dss_device; + +extern const device_t lpt_hasp_savquest_device; + +extern int lpt_device_available(int id); +#ifdef EMU_DEVICE_H +extern const device_t *lpt_device_getdevice(const int id); +#endif +extern int lpt_device_has_config(const int id); +extern const char *lpt_device_get_name(int id); +extern const char *lpt_device_get_internal_name(int id); +extern int lpt_device_get_from_internal_name(const char *str); + extern void lpt_write(uint16_t port, uint8_t val, void *priv); extern void lpt_write_to_fifo(void *priv, uint8_t val); @@ -109,24 +116,6 @@ extern uint8_t lpt_read_ecp_mode(lpt_t *dev); extern void lpt_irq(void *priv, int raise); -extern int lpt_device_get_from_internal_name(const char *str); - -extern const char *lpt_device_get_name(int id); -extern const char *lpt_device_get_internal_name(int id); - -#ifdef EMU_DEVICE_H -extern const device_t *lpt_device_getdevice(const int id); -#endif - -extern int lpt_device_has_config(const int id); - -extern const lpt_device_t lpt_dac_device; -extern const lpt_device_t lpt_dac_stereo_device; - -extern const lpt_device_t dss_device; - -extern const lpt_device_t lpt_hasp_savquest_device; - extern void lpt_set_ext(lpt_t *dev, uint8_t ext); extern void lpt_set_ecp(lpt_t *dev, uint8_t ecp); extern void lpt_set_epp(lpt_t *dev, uint8_t epp); @@ -143,12 +132,22 @@ extern void lpt_port_remove(lpt_t *dev); extern void lpt1_remove_ams(lpt_t *dev); extern void lpt_devices_init(void); +extern void * lpt_attach(int port, + void (*write_data)(uint8_t val, void *priv), + void (*write_ctrl)(uint8_t val, void *priv), + void (*strobe)(uint8_t old, uint8_t val,void *priv), + uint8_t (*read_status)(void *priv), + uint8_t (*read_ctrl)(void *priv), + void (*epp_write_data)(uint8_t is_addr, uint8_t val, void *priv), + void (*epp_request_read)(uint8_t is_addr, void *priv), + void *priv); extern void lpt_devices_close(void); extern void lpt_set_next_inst(int ni); extern void lpt_set_3bc_used(int is_3bc_used); extern void lpt_standalone_init(void); +extern void lpt_ports_reset(void); extern const device_t lpt_port_device; diff --git a/src/include/86box/network.h b/src/include/86box/network.h index 0642c3f53c..2c91a6d9f5 100644 --- a/src/include/86box/network.h +++ b/src/include/86box/network.h @@ -244,10 +244,8 @@ extern const device_t pcnet_am79c973_onboard_device; extern const device_t modem_device; /* PLIP */ -#ifdef EMU_LPT_H -extern const lpt_device_t lpt_plip_device; -#endif -extern const device_t plip_device; +extern const device_t lpt_plip_device; +extern const device_t plip_device; /* Realtek RTL8139C+ */ extern const device_t rtl8139c_plus_device; diff --git a/src/include/86box/prt_devs.h b/src/include/86box/prt_devs.h index d136d9d933..05b5a7d942 100644 --- a/src/include/86box/prt_devs.h +++ b/src/include/86box/prt_devs.h @@ -1,15 +1,11 @@ #ifndef EMU_PRT_DEVS_H #define EMU_PRT_DEVS_H -extern const lpt_device_t lpt_prt_text_device; -extern const device_t prt_text_device; -extern const lpt_device_t lpt_prt_escp_device; -extern const device_t prt_escp_device; -extern const lpt_device_t lpt_prt_ps_device; -extern const device_t prt_ps_device; +extern const device_t lpt_prt_text_device; +extern const device_t lpt_prt_escp_device; +extern const device_t lpt_prt_ps_device; #ifdef USE_PCL -extern const lpt_device_t lpt_prt_pcl_device; -extern const device_t prt_pcl_device; +extern const device_t lpt_prt_pcl_device; #endif #endif /*EMU_PRT_DEVS_H*/ diff --git a/src/network/net_plip.c b/src/network/net_plip.c index 36df49153c..e472ea6c3f 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -441,13 +441,14 @@ plip_rx(void *priv, uint8_t *buf, int io_len) } static void * -plip_lpt_init(void *lpt) +plip_lpt_init(const device_t *info) { plip_t *dev = (plip_t *) calloc(1, sizeof(plip_t)); plip_log(1, "PLIP: lpt_init()\n"); - dev->lpt = lpt; + dev->lpt = lpt_attach(info->local & 0xf, plip_write_data, plip_write_ctrl, NULL, plip_read_status, NULL, NULL, NULL, dev); + memset(dev->mac, 0xfc, 6); /* static MAC used by Linux; just a placeholder */ dev->status = 0x80; @@ -485,24 +486,22 @@ plip_close(void *priv) free(priv); } -const lpt_device_t lpt_plip_device = { - .name = "Parallel Line Internet Protocol", - .internal_name = "plip", - .init = plip_lpt_init, - .close = plip_close, - .write_data = plip_write_data, - .write_ctrl = plip_write_ctrl, - .strobe = NULL, - .read_status = plip_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL +const device_t lpt_plip_device = { + .name = "Parallel Line Internet Protocol (LPT)", + .internal_name = "plip", + .flags = DEVICE_LPT, + .local = 0, + .init = plip_lpt_init, + .close = plip_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; const device_t plip_device = { - .name = "Parallel Line Internet Protocol", + .name = "Parallel Line Internet Protocol (Network)", .internal_name = "plip", .flags = DEVICE_LPT, .local = 0, diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index a240729714..42702dce37 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1979,7 +1979,7 @@ read_status(void *priv) } static void * -escp_init(void *lpt) +escp_init(const device_t *info) { escp_t *dev = NULL; @@ -1995,7 +1995,8 @@ escp_init(void *lpt) /* Initialize a device instance. */ dev = (escp_t *) calloc(1, sizeof(escp_t)); dev->ctrl = 0x04; - dev->lpt = lpt; + + dev->lpt = lpt_attach(info->local & 0xf, write_data, write_ctrl, strobe, read_status, read_ctrl, NULL, NULL, dev); rom_get_full_path(dev->fontpath, "roms/printer/fonts/"); @@ -2109,13 +2110,13 @@ static const device_config_t lpt_prt_escp_config[] = { #endif // clang-format on -const device_t prt_escp_device = { +const device_t lpt_prt_escp_device = { .name = "Generic ESC/P 2 Dot-Matrix Printer", .internal_name = "dot_matrix", .flags = DEVICE_LPT, .local = 0, - .init = NULL, - .close = NULL, + .init = escp_init, + .close = escp_close, .reset = NULL, .available = NULL, .speed_changed = NULL, @@ -2126,20 +2127,3 @@ const device_t prt_escp_device = { .config = NULL #endif }; - -const lpt_device_t lpt_prt_escp_device = { - .name = "Generic ESC/P 2 Dot-Matrix Printer", - .internal_name = "dot_matrix", - .init = escp_init, - .close = escp_close, - .write_data = write_data, - .write_ctrl = write_ctrl, - .strobe = strobe, - .read_status = read_status, - .read_ctrl = read_ctrl, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL, - .cfgdevice = (device_t *) &prt_escp_device -}; diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index bb153723ce..60e87e15e7 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -465,15 +465,16 @@ ps_read_status(void *priv) } static void * -ps_init(void *lpt) +ps_init(const device_t *info) { ps_t *dev = (ps_t *) calloc(1, sizeof(ps_t)); gsapi_revision_t rev; dev->ctrl = 0x04; - dev->lpt = lpt; dev->pcl = false; + dev->lpt = lpt_attach(info->local & 0xf, ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); + /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); #ifdef PATH_GHOSTSCRIPT_DLL_ALT1 @@ -513,15 +514,16 @@ ps_init(void *lpt) #ifdef USE_PCL static void * -pcl_init(void *lpt) +pcl_init(const device_t *info) { ps_t *dev = (ps_t *) calloc(1, sizeof(ps_t)); gsapi_revision_t rev; dev->ctrl = 0x04; - dev->lpt = lpt; dev->pcl = true; + dev->lpt = lpt_attach(info->local & 0xf, ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); + /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL, ghostscript_imports); #ifdef PATH_GHOSTPCL_DLL_ALT1 @@ -579,36 +581,32 @@ ps_close(void *priv) free(dev); } -const lpt_device_t lpt_prt_ps_device = { - .name = "Generic PostScript Printer", - .internal_name = "postscript", - .init = ps_init, - .close = ps_close, - .write_data = ps_write_data, - .write_ctrl = ps_write_ctrl, - .strobe = ps_strobe, - .read_status = ps_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL +const device_t lpt_prt_ps_device = { + .name = "Generic PostScript Printer", + .internal_name = "postscript", + .flags = DEVICE_LPT, + .local = 0, + .init = ps_init, + .close = ps_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; #ifdef USE_PCL -const lpt_device_t lpt_prt_pcl_device = { - .name = "Generic PCL5e Printer", - .internal_name = "pcl", - .init = pcl_init, - .close = ps_close, - .write_data = ps_write_data, - .write_ctrl = ps_write_ctrl, - .strobe = ps_strobe, - .read_status = ps_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL +const device_t lpt_prt_pcl_device = { + .name = "Generic PCL5e Printer", + .internal_name = "pcl", + .flags = DEVICE_LPT, + .local = 0, + .init = pcl_init, + .close = ps_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; #endif diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index af601af75d..0e27bf1af8 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -455,13 +455,13 @@ read_status(void *priv) } static void * -prnt_init(void *lpt) +prnt_init(const device_t *info) { /* Initialize a device instance. */ prnt_t *dev = (prnt_t *) calloc(1, sizeof(prnt_t)); dev->ctrl = 0x04; - dev->lpt = lpt; + dev->lpt = lpt_attach(info->local & 0xf, write_data, write_ctrl, strobe, read_status, NULL, NULL, NULL, dev); /* Initialize parameters. */ reset_printer(dev); @@ -523,13 +523,13 @@ static const device_config_t lpt_prt_text_config[] = { #endif // clang-format on -const device_t prt_text_device = { +const device_t lpt_prt_text_device = { .name = "Generic Text Printer", .internal_name = "text_prt", .flags = DEVICE_LPT, .local = 0, - .init = NULL, - .close = NULL, + .init = prnt_init, + .close = prnt_close, .reset = NULL, .available = NULL, .speed_changed = NULL, @@ -540,20 +540,3 @@ const device_t prt_text_device = { .config = NULL #endif }; - -const lpt_device_t lpt_prt_text_device = { - .name = "Generic Text Printer", - .internal_name = "text_prt", - .init = prnt_init, - .close = prnt_close, - .write_data = write_data, - .write_ctrl = write_ctrl, - .strobe = strobe, - .read_status = read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL, - .cfgdevice = (device_t *) &prt_text_device -}; diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 33b197230c..f2268cd0f0 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -89,11 +89,11 @@ dac_get_buffer(int32_t *buffer, int len, void *priv) } static void * -dac_init(void *lpt) +dac_init(UNUSED(const device_t *info)) { lpt_dac_t *lpt_dac = calloc(1, sizeof(lpt_dac_t)); - lpt_dac->lpt = lpt; + lpt_dac->lpt = lpt_attach(info->local & 0xf, dac_write_data, dac_write_ctrl, dac_strobe, dac_read_status, NULL, NULL, NULL, lpt_dac); sound_add_handler(dac_get_buffer, lpt_dac); @@ -101,9 +101,9 @@ dac_init(void *lpt) } static void * -dac_stereo_init(void *lpt) +dac_stereo_init(const device_t *info) { - lpt_dac_t *lpt_dac = dac_init(lpt); + lpt_dac_t *lpt_dac = dac_init(info); lpt_dac->is_stereo = 1; @@ -117,34 +117,30 @@ dac_close(void *priv) free(lpt_dac); } -const lpt_device_t lpt_dac_device = { - .name = "LPT DAC / Covox Speech Thing", - .internal_name = "lpt_dac", - .init = dac_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .strobe = dac_strobe, - .read_status = dac_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL +const device_t lpt_dac_device = { + .name = "LPT DAC / Covox Speech Thing", + .internal_name = "lpt_dac", + .flags = DEVICE_LPT, + .local = 0, + .init = dac_init, + .close = dac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; -const lpt_device_t lpt_dac_stereo_device = { - .name = "Stereo LPT DAC", - .internal_name = "lpt_dac_stereo", - .init = dac_stereo_init, - .close = dac_close, - .write_data = dac_write_data, - .write_ctrl = dac_write_ctrl, - .strobe = dac_strobe, - .read_status = dac_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL +const device_t lpt_dac_stereo_device = { + .name = "Stereo LPT DAC", + .internal_name = "lpt_dac_stereo", + .flags = DEVICE_LPT, + .local = 0, + .init = dac_stereo_init, + .close = dac_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 5ea0048f47..2581d78732 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -114,11 +114,11 @@ dss_callback(void *priv) } static void * -dss_init(void *lpt) +dss_init(UNUSED(const device_t *info)) { dss_t *dss = calloc(1, sizeof(dss_t)); - dss->lpt = lpt; + dss->lpt = lpt_attach(info->local & 0xf, dss_write_data, dss_write_ctrl, NULL, dss_read_status, NULL, NULL, NULL, dss); sound_add_handler(dss_get_buffer, dss); timer_add(&dss->timer, dss_callback, dss, 1); @@ -133,18 +133,16 @@ dss_close(void *priv) free(dss); } -const lpt_device_t dss_device = { - .name = "Disney Sound Source", - .internal_name = "dss", - .init = dss_init, - .close = dss_close, - .write_data = dss_write_data, - .strobe = NULL, - .write_ctrl = dss_write_ctrl, - .read_status = dss_read_status, - .read_ctrl = NULL, - .epp_write_data = NULL, - .epp_request_read = NULL, - .priv = NULL, - .lpt = NULL +const device_t dss_device = { + .name = "Disney Sound Source", + .internal_name = "dss", + .flags = DEVICE_LPT, + .local = 0, + .init = dss_init, + .close = dss_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL }; From 51e0e8832948f050beef4b4093a221df658af04e Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 27 Jan 2026 09:40:53 +0100 Subject: [PATCH 52/58] More LPT device sanitization, un-dev-branch the Generic PCL printer, add language selection to it and the PostScript printer (including a Raw option), and translate the missing strings. --- CMakeLists.txt | 1 - src/device/hasp.c | 2 +- src/device/lpt.c | 9 +- src/include/86box/lpt.h | 3 +- src/include/86box/prt_devs.h | 2 - src/network/net_plip.c | 2 +- src/printer/CMakeLists.txt | 4 - src/printer/prt_escp.c | 2 +- src/printer/prt_ps.c | 339 ++++++++++++++++++++++------------- src/printer/prt_text.c | 2 +- src/qt/languages/86box.pot | 3 + src/qt/languages/ca-ES.po | 9 +- src/qt/languages/cs-CZ.po | 6 +- src/qt/languages/de-DE.po | 9 +- src/qt/languages/el-GR.po | 7 +- src/qt/languages/es-ES.po | 9 +- src/qt/languages/fi-FI.po | 9 +- src/qt/languages/fr-FR.po | 9 +- src/qt/languages/hr-HR.po | 9 +- src/qt/languages/it-IT.po | 9 +- src/qt/languages/ja-JP.po | 9 +- src/qt/languages/ko-KR.po | 9 +- src/qt/languages/nb-NO.po | 9 +- src/qt/languages/nl-NL.po | 9 +- src/qt/languages/pl-PL.po | 9 +- src/qt/languages/pt-BR.po | 9 +- src/qt/languages/pt-PT.po | 9 +- src/qt/languages/ru-RU.po | 3 + src/qt/languages/sk-SK.po | 9 +- src/qt/languages/sl-SI.po | 9 +- src/qt/languages/sv-SE.po | 9 +- src/qt/languages/tr-TR.po | 3 + src/qt/languages/uk-UA.po | 9 +- src/qt/languages/vi-VN.po | 9 +- src/qt/languages/zh-CN.po | 3 + src/qt/languages/zh-TW.po | 3 + src/sound/snd_lpt_dac.c | 2 +- src/sound/snd_lpt_dss.c | 2 +- 38 files changed, 366 insertions(+), 203 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 667df52214..b64902c122 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -180,7 +180,6 @@ cmake_dependent_option(ISAMEM_RAMPAGE "AST Rampage" cmake_dependent_option(ISAMEM_IAB "Intel Above Board" ON "DEV_BRANCH" OFF) cmake_dependent_option(ISAMEM_BRAT "BocaRAM/AT" ON "DEV_BRANCH" OFF) cmake_dependent_option(OPL4ML "OPL4-ML daughterboard" ON "DEV_BRANCH" OFF) -cmake_dependent_option(PCL "Generic PCL5e Printer" ON "DEV_BRANCH" OFF) cmake_dependent_option(SIO_DETECT "Super I/O Detection Helper" ON "DEV_BRANCH" OFF) cmake_dependent_option(WACOM "Wacom Input Devices" ON "DEV_BRANCH" OFF) cmake_dependent_option(XL24 "ATI VGA Wonder XL24 (ATI-28800-6)" ON "DEV_BRANCH" OFF) diff --git a/src/device/hasp.c b/src/device/hasp.c index 920f482572..f4b6bc0ad0 100644 --- a/src/device/hasp.c +++ b/src/device/hasp.c @@ -308,7 +308,7 @@ hasp_init(const device_t *info, int type) hasp_log("HASP: init(%d)\n", type); - dev->lpt = lpt_attach(info->local & 0xf, hasp_write_data, NULL, NULL, hasp_read_status, NULL, NULL, NULL, dev); + dev->lpt = lpt_attach(hasp_write_data, NULL, NULL, hasp_read_status, NULL, NULL, NULL, dev); dev->type = &hasp_types[type]; dev->status = 0x80; diff --git a/src/device/lpt.c b/src/device/lpt.c index b6ec9f0314..a7fb5ac2da 100644 --- a/src/device/lpt.c +++ b/src/device/lpt.c @@ -59,9 +59,7 @@ static const struct { { &lpt_prt_text_device }, { &lpt_prt_escp_device }, { &lpt_prt_ps_device }, -#ifdef USE_PCL { &lpt_prt_pcl_device }, -#endif { &lpt_plip_device }, { &lpt_hasp_savquest_device }, { NULL } @@ -145,13 +143,12 @@ lpt_devices_init(void) if ((lpt_devices[lpt_ports[i].device].device != NULL) && (lpt_devices[lpt_ports[i].device].device != &lpt_none_device)) - device_add_params((device_t *) lpt_devices[lpt_ports[i].device].device, (void *) (uintptr_t) i); + device_add_inst((device_t *) lpt_devices[lpt_ports[i].device].device, i + 1); } } void * -lpt_attach(int port, - void (*write_data)(uint8_t val, void *priv), +lpt_attach(void (*write_data)(uint8_t val, void *priv), void (*write_ctrl)(uint8_t val, void *priv), void (*strobe)(uint8_t old, uint8_t val,void *priv), uint8_t (*read_status)(void *priv), @@ -160,6 +157,8 @@ lpt_attach(int port, void (*epp_request_read)(uint8_t is_addr, void *priv), void *priv) { + int port = device_get_instance() - 1; + lpt_devs[port].write_data = write_data; lpt_devs[port].write_ctrl = write_ctrl; lpt_devs[port].strobe = strobe; diff --git a/src/include/86box/lpt.h b/src/include/86box/lpt.h index 89f7cb5d17..fe5442379f 100644 --- a/src/include/86box/lpt.h +++ b/src/include/86box/lpt.h @@ -132,8 +132,7 @@ extern void lpt_port_remove(lpt_t *dev); extern void lpt1_remove_ams(lpt_t *dev); extern void lpt_devices_init(void); -extern void * lpt_attach(int port, - void (*write_data)(uint8_t val, void *priv), +extern void * lpt_attach(void (*write_data)(uint8_t val, void *priv), void (*write_ctrl)(uint8_t val, void *priv), void (*strobe)(uint8_t old, uint8_t val,void *priv), uint8_t (*read_status)(void *priv), diff --git a/src/include/86box/prt_devs.h b/src/include/86box/prt_devs.h index 05b5a7d942..3431829461 100644 --- a/src/include/86box/prt_devs.h +++ b/src/include/86box/prt_devs.h @@ -4,8 +4,6 @@ extern const device_t lpt_prt_text_device; extern const device_t lpt_prt_escp_device; extern const device_t lpt_prt_ps_device; -#ifdef USE_PCL extern const device_t lpt_prt_pcl_device; -#endif #endif /*EMU_PRT_DEVS_H*/ diff --git a/src/network/net_plip.c b/src/network/net_plip.c index e472ea6c3f..f61c046461 100644 --- a/src/network/net_plip.c +++ b/src/network/net_plip.c @@ -447,7 +447,7 @@ plip_lpt_init(const device_t *info) plip_log(1, "PLIP: lpt_init()\n"); - dev->lpt = lpt_attach(info->local & 0xf, plip_write_data, plip_write_ctrl, NULL, plip_read_status, NULL, NULL, NULL, dev); + dev->lpt = lpt_attach(plip_write_data, plip_write_ctrl, NULL, plip_read_status, NULL, NULL, NULL, dev); memset(dev->mac, 0xfc, 6); /* static MAC used by Linux; just a placeholder */ diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index 0efb2aec24..1b4d9c0c51 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -23,10 +23,6 @@ add_library(print OBJECT prt_ps.c ) -if(PCL) - target_compile_definitions(print PRIVATE USE_PCL) -endif() - if(APPLE) find_library(GHOSTSCRIPT_LIB gs) if (NOT GHOSTSCRIPT_LIB) diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 42702dce37..2a50ae54f1 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -1996,7 +1996,7 @@ escp_init(const device_t *info) dev = (escp_t *) calloc(1, sizeof(escp_t)); dev->ctrl = 0x04; - dev->lpt = lpt_attach(info->local & 0xf, write_data, write_ctrl, strobe, read_status, read_ctrl, NULL, NULL, dev); + dev->lpt = lpt_attach(write_data, write_ctrl, strobe, read_status, read_ctrl, NULL, NULL, dev); rom_get_full_path(dev->fontpath, "roms/printer/fonts/"); diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 60e87e15e7..77ecf0a5fb 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -61,40 +61,55 @@ #define POSTSCRIPT_BUFFER_LENGTH 65536 +enum { + LANG_RAW = 0, + LANG_PS, + LANG_PCL_5E, + LANG_PCL_5C, + LANG_HP_RTL, + LANG_PCL_6 +}; + typedef struct ps_t { const char *name; - void *lpt; + void * lpt; + + pc_timer_t pulse_timer; + pc_timer_t timeout_timer; + + bool ack; + bool select; + bool busy; + bool int_pending; + bool error; + bool autofeed; + bool pcl; + bool pending; + bool pjl; + bool pjl_command; + + char data; - pc_timer_t pulse_timer; - pc_timer_t timeout_timer; + char printer_path[260]; + char filename[260]; - char data; - bool ack; - bool select; - bool busy; - bool int_pending; - bool error; - bool autofeed; - bool pcl; - bool pending; - bool pjl; - bool pjl_command; - uint8_t ctrl; - uint8_t pcl_escape; - uint16_t pjl_command_start; + char buffer[POSTSCRIPT_BUFFER_LENGTH]; - char printer_path[260]; + uint8_t ctrl; + uint8_t pcl_escape; - char filename[260]; + uint16_t pjl_command_start; - char buffer[POSTSCRIPT_BUFFER_LENGTH]; - size_t buffer_pos; + int lang; + + size_t buffer_pos; } ps_t; typedef struct gsapi_revision_s { const char *product; const char *copyright; + long revision; long revisiondate; } gsapi_revision_t; @@ -155,8 +170,23 @@ convert_to_pdf(ps_t *dev) gsargv[arg++] = "-dSAFER"; gsargv[arg++] = "-sDEVICE=pdfwrite"; if (dev->pcl) { - gsargv[arg++] = "-LPCL"; - gsargv[arg++] = "-lPCL5C"; + if (dev->lang == LANG_PCL_6) + gsargv[arg++] = "-LPCLXL"; + else { + gsargv[arg++] = "-LPCL"; + switch (dev->lang) { + default: + case LANG_PCL_5E: + gsargv[arg++] = "-lPCL5E"; + break; + case LANG_PCL_5C: + gsargv[arg++] = "-lPCL5C"; + break; + case LANG_HP_RTL: + gsargv[arg++] = "-lRTL"; + break; + } + } } gsargv[arg++] = "-q"; gsargv[arg++] = "-o"; @@ -196,7 +226,7 @@ reset_ps(ps_t *dev) dev->ack = false; if (dev->pending) { - if (ghostscript_handle != NULL) + if ((dev->lang != LANG_RAW) && (ghostscript_handle != NULL)) convert_to_pdf(dev); dev->filename[0] = 0; @@ -220,8 +250,14 @@ write_buffer(ps_t *dev, bool finish) if (dev->buffer_pos == 0) return; - if (dev->filename[0] == 0) - plat_tempfile(dev->filename, NULL, dev->pcl ? ".pcl" : ".ps"); + if (dev->filename[0] == 0) { + if (dev->lang == LANG_RAW) + plat_tempfile(dev->filename, NULL, ".raw"); + else if (dev->pcl) + plat_tempfile(dev->filename, NULL, (dev->lang == LANG_PCL_6) ? ".pxl" : ".pcl"); + else + plat_tempfile(dev->filename, NULL, ".ps"); + } strcpy(path, dev->printer_path); path_slash(path); @@ -244,7 +280,7 @@ write_buffer(ps_t *dev, bool finish) dev->buffer_pos = 0; if (finish) { - if (ghostscript_handle != NULL) + if ((dev->lang != LANG_RAW) && (ghostscript_handle != NULL)) convert_to_pdf(dev); dev->filename[0] = 0; @@ -262,7 +298,7 @@ timeout_timer(void *priv) if (dev->buffer_pos != 0) write_buffer(dev, true); else if (dev->pending) { - if (ghostscript_handle != NULL) + if ((dev->lang != LANG_RAW) && (ghostscript_handle != NULL)) convert_to_pdf(dev); dev->filename[0] = 0; @@ -284,97 +320,115 @@ ps_write_data(uint8_t val, void *priv) dev->data = (char) val; } -static void -process_data(ps_t *dev) +static int +process_escape(ps_t *dev, int do_pjl) { - /* On PCL, check for escape sequences. */ - if (dev->pcl) { - if (dev->pjl) { - dev->buffer[dev->buffer_pos++] = dev->data; - - /* Filter out any PJL commands. */ - if (dev->pjl_command && (dev->data == '\n')) { - dev->pjl_command = false; - if (!memcmp(&(dev->buffer[dev->pjl_command_start]), "@PJL ENTER LANGUAGE=PCL", 0x17)) - dev->pjl = false; - else if (!memcmp(&(dev->buffer[dev->pjl_command_start]), "@PJL ENTER LANGUAGE=POSTSCRIPT", 0x1e)) - fatal("Printing PostScript using the PCL printer is not (yet) supported!\n"); - dev->buffer[dev->buffer_pos] = 0x00; - dev->buffer_pos = dev->pjl_command_start; - } else if (!dev->pjl_command && (dev->buffer_pos >= 0x05) && !memcmp(&(dev->buffer[dev->buffer_pos - 0x5]), "@PJL ", 0x05)) { - dev->pjl_command = true; - dev->pjl_command_start = dev->buffer_pos - 0x05; - } else if (!dev->pjl_command && (dev->data == 0x1b)) - /* The universal exit code is also valid in PJL. */ - dev->pcl_escape = 1; - - dev->buffer[dev->buffer_pos] = 0; - return; - } else if (dev->data == 0x1b) - dev->pcl_escape = 1; - else switch (dev->pcl_escape) { - case 1: - dev->pcl_escape = (dev->data == 0x25) ? 2 : 0; - break; - case 2: - dev->pcl_escape = (dev->data == 0x2d) ? 3 : 0; - break; - case 3: - dev->pcl_escape = (dev->data == 0x31) ? 4 : 0; - break; - case 4: - dev->pcl_escape = (dev->data == 0x32) ? 5 : 0; - break; - case 5: - dev->pcl_escape = (dev->data == 0x33) ? 6 : 0; - break; - case 6: - dev->pcl_escape = (dev->data == 0x34) ? 7 : 0; - break; - case 7: - dev->pcl_escape = (dev->data == 0x35) ? 8 : 0; - break; - case 8: - dev->pcl_escape = 0; - if (dev->data == 0x58) { + int ret = 0; + + if (dev->data == 0x1b) + dev->pcl_escape = 1; + else switch (dev->pcl_escape) { + case 1: + dev->pcl_escape = (dev->data == 0x25) ? 2 : 0; + break; + case 2: + dev->pcl_escape = (dev->data == 0x2d) ? 3 : 0; + break; + case 3: + dev->pcl_escape = (dev->data == 0x31) ? 4 : 0; + break; + case 4: + dev->pcl_escape = (dev->data == 0x32) ? 5 : 0; + break; + case 5: + dev->pcl_escape = (dev->data == 0x33) ? 6 : 0; + break; + case 6: + dev->pcl_escape = (dev->data == 0x34) ? 7 : 0; + break; + case 7: + dev->pcl_escape = (dev->data == 0x35) ? 8 : 0; + break; + case 8: + dev->pcl_escape = 0; + if (dev->data == 0x58) { + if (do_pjl) dev->pjl = true; - dev->buffer[dev->buffer_pos++] = dev->data; - dev->buffer[dev->buffer_pos] = 0; + dev->buffer[dev->buffer_pos++] = dev->data; + dev->buffer[dev->buffer_pos] = 0; - if (dev->pjl) - /* Wipe the slate clean so that there won't be a bogus empty page output to PDF. */ - dev->pending = false; - else if (dev->buffer_pos > 9) - write_buffer(dev, true); - return; - } - break; + /* Wipe the slate clean so that there won't be a bogus empty page output to PDF. */ + dev->pending = false; + ret = 1; + } + break; + } + + return ret; +} + +static void +process_data(ps_t *dev) +{ + if (dev->lang == LANG_RAW) { + if ((dev->data == 0x1b) || (dev->pcl_escape > 0)) { + if (process_escape(dev, 0)) + return; } - } else if ((dev->data < 0x20) || (dev->data == 0x7f)) { - /* On PostScript, check for non-printable characters. */ - switch (dev->data) { - /* The following characters are considered white-space - by the PostScript specification */ - case '\t': - case '\n': - case '\f': - case '\r': - break; - - /* Same with NUL, except we better change it to a space first */ - case '\0': - dev->data = ' '; - break; - - /* Ctrl+D (0x04) marks the end of the document */ - case '\4': - write_buffer(dev, true); + } else { + /* On PCL, check for escape sequences. */ + if (dev->pcl) { + if (dev->pjl) { + dev->buffer[dev->buffer_pos++] = dev->data; + + /* Filter out any PJL commands. */ + if (dev->pjl_command && (dev->data == '\n')) { + dev->pjl_command = false; + if (!memcmp(&(dev->buffer[dev->pjl_command_start]), "@PJL ENTER LANGUAGE=PCL", 0x17)) + dev->pjl = false; + else if (!memcmp(&(dev->buffer[dev->pjl_command_start]), "@PJL ENTER LANGUAGE=POSTSCRIPT", 0x1e)) + fatal("Printing PostScript using the PCL printer is not (yet) supported!\n"); + dev->buffer[dev->buffer_pos] = 0x00; + dev->buffer_pos = dev->pjl_command_start; + } else if (!dev->pjl_command && (dev->buffer_pos >= 0x05) && !memcmp(&(dev->buffer[dev->buffer_pos - 0x5]), "@PJL ", 0x05)) { + dev->pjl_command = true; + dev->pjl_command_start = dev->buffer_pos - 0x05; + } else if (!dev->pjl_command && (dev->data == 0x1b)) + /* The universal exit code is also valid in PJL. */ + dev->pcl_escape = 1; + + dev->buffer[dev->buffer_pos] = 0; return; + } else if ((dev->data == 0x1b) || (dev->pcl_escape > 0)) { + if (process_escape(dev, 1)) + return; + } + } else if ((dev->data < 0x20) || (dev->data == 0x7f)) { + /* On PostScript, check for non-printable characters. */ + switch (dev->data) { + /* The following characters are considered white-space + by the PostScript specification */ + case '\t': + case '\n': + case '\f': + case '\r': + break; + + /* Same with NUL, except we better change it to a space first */ + case '\0': + dev->data = ' '; + break; + + /* Ctrl+D (0x04) marks the end of the document */ + case '\4': + write_buffer(dev, true); + return; - /* Don't bother with the others */ - default: - return; + /* Don't bother with the others */ + default: + return; + } } } @@ -473,7 +527,8 @@ ps_init(const device_t *info) dev->ctrl = 0x04; dev->pcl = false; - dev->lpt = lpt_attach(info->local & 0xf, ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); + dev->lpt = lpt_attach(ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); + dev->lang = device_get_config_int("language"); /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); @@ -512,7 +567,6 @@ ps_init(const device_t *info) return dev; } -#ifdef USE_PCL static void * pcl_init(const device_t *info) { @@ -522,7 +576,8 @@ pcl_init(const device_t *info) dev->ctrl = 0x04; dev->pcl = true; - dev->lpt = lpt_attach(info->local & 0xf, ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); + dev->lpt = lpt_attach(ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); + dev->lang = device_get_config_int("language"); /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL, ghostscript_imports); @@ -560,7 +615,6 @@ pcl_init(const device_t *info) return dev; } -#endif static void ps_close(void *priv) @@ -581,6 +635,51 @@ ps_close(void *priv) free(dev); } +// clang-format off +static const device_config_t lpt_prt_ps_config[] = { + { + .name = "language", + .description = "Language", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = LANG_PS, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Raw", .value = LANG_RAW }, + { .description = "PDF (PostScript)", .value = LANG_PS }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + +// clang-format off +static const device_config_t lpt_prt_pcl_config[] = { + { + .name = "language", + .description = "Language", + .type = CONFIG_SELECTION, + .default_string = NULL, + .default_int = LANG_PCL_5E, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { + { .description = "Raw", .value = LANG_RAW }, + { .description = "PDF (PCL 5e)", .value = LANG_PCL_5E }, + { .description = "PDF (PCL 5c)", .value = LANG_PCL_5C }, + { .description = "PDF (HP-RTL)", .value = LANG_HP_RTL }, + { .description = "PDF (PCL 6)", .value = LANG_PCL_6 }, + { .description = "" } + }, + .bios = { { 0 } } + }, + { .name = "", .description = "", .type = CONFIG_END } +}; +// clang-format on + const device_t lpt_prt_ps_device = { .name = "Generic PostScript Printer", .internal_name = "postscript", @@ -592,12 +691,11 @@ const device_t lpt_prt_ps_device = { .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = lpt_prt_ps_config }; -#ifdef USE_PCL const device_t lpt_prt_pcl_device = { - .name = "Generic PCL5e Printer", + .name = "Generic PCL Printer", .internal_name = "pcl", .flags = DEVICE_LPT, .local = 0, @@ -607,6 +705,5 @@ const device_t lpt_prt_pcl_device = { .available = NULL, .speed_changed = NULL, .force_redraw = NULL, - .config = NULL + .config = lpt_prt_pcl_config }; -#endif diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index 0e27bf1af8..ad49bc56f3 100644 --- a/src/printer/prt_text.c +++ b/src/printer/prt_text.c @@ -461,7 +461,7 @@ prnt_init(const device_t *info) prnt_t *dev = (prnt_t *) calloc(1, sizeof(prnt_t)); dev->ctrl = 0x04; - dev->lpt = lpt_attach(info->local & 0xf, write_data, write_ctrl, strobe, read_status, NULL, NULL, NULL, dev); + dev->lpt = lpt_attach(write_data, write_ctrl, strobe, read_status, NULL, NULL, NULL, dev); /* Initialize parameters. */ reset_printer(dev); diff --git a/src/qt/languages/86box.pot b/src/qt/languages/86box.pot index c5d1d25144..c62c18ea84 100644 --- a/src/qt/languages/86box.pot +++ b/src/qt/languages/86box.pot @@ -3017,3 +3017,6 @@ msgstr "" msgid "To change the system directory, stop all running machines." msgstr "" + +msgid "Raw" +msgstr "" diff --git a/src/qt/languages/ca-ES.po b/src/qt/languages/ca-ES.po index ad9dd6eb11..0c1c8ac893 100644 --- a/src/qt/languages/ca-ES.po +++ b/src/qt/languages/ca-ES.po @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "&Permetre recompilació" msgid "&Fast forward" -msgstr "" +msgstr "&Avançar ràpidament" msgid "Fast forward" -msgstr "" +msgstr "Avançar ràpidament" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Per canviar el directori del sistema, atureu totes les màquines en funcionament." + +msgid "Raw" +msgstr "En brut" diff --git a/src/qt/languages/cs-CZ.po b/src/qt/languages/cs-CZ.po index 5e89f736ac..1df82475fa 100644 --- a/src/qt/languages/cs-CZ.po +++ b/src/qt/languages/cs-CZ.po @@ -3022,5 +3022,7 @@ msgid "Fast forward" msgstr "Zrychlit" msgid "To change the system directory, stop all running machines." -msgstr "" -"Před změnou systémového adresáře nejprve zastavte všechny běžící počítače." +msgstr "Před změnou systémového adresáře nejprve zastavte všechny běžící počítače." + +msgid "Raw" +msgstr "Surový" diff --git a/src/qt/languages/de-DE.po b/src/qt/languages/de-DE.po index 38e8298617..f377fcad0f 100644 --- a/src/qt/languages/de-DE.po +++ b/src/qt/languages/de-DE.po @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "Recompilierung &zulassen" msgid "&Fast forward" -msgstr "" +msgstr "&Schnellvorlauf" msgid "Fast forward" -msgstr "" +msgstr "Schnellvorlauf" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Um das Systemverzeichnis zu ändern, stoppen Sie alle laufenden Maschinen." + +msgid "Raw" +msgstr "Roh" diff --git a/src/qt/languages/el-GR.po b/src/qt/languages/el-GR.po index 5cb45bded0..6933075a56 100644 --- a/src/qt/languages/el-GR.po +++ b/src/qt/languages/el-GR.po @@ -3083,6 +3083,7 @@ msgid "Fast forward" msgstr "Γρήγορα μπροστά" msgid "To change the system directory, stop all running machines." -msgstr "" -"Για να αλλάξετε τον κατάλογο συστήματος, σταματήστε πρώτα όλες τις μηχανές " -"σε λειτουργία." +msgstr "Για να αλλάξετε τον κατάλογο συστήματος, σταματήστε πρώτα όλες τις μηχανές σε λειτουργία." + +msgid "Raw" +msgstr "Αρχικος" diff --git a/src/qt/languages/es-ES.po b/src/qt/languages/es-ES.po index 3d339efd01..4f34c34f55 100644 --- a/src/qt/languages/es-ES.po +++ b/src/qt/languages/es-ES.po @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "&Permitir recompilación" msgid "&Fast forward" -msgstr "" +msgstr "&Avance rápido" msgid "Fast forward" -msgstr "" +msgstr "Avance rápido" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Para cambiar el directorio del sistema, detenga todas las máquinas en funcionamiento." + +msgid "Raw" +msgstr "Plano" diff --git a/src/qt/languages/fi-FI.po b/src/qt/languages/fi-FI.po index fd6add6960..a5f36d2d48 100644 --- a/src/qt/languages/fi-FI.po +++ b/src/qt/languages/fi-FI.po @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "&Salli uudelleenkääntäminen" msgid "&Fast forward" -msgstr "" +msgstr "&Nopea eteneminen" msgid "Fast forward" -msgstr "" +msgstr "Nopea eteneminen" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Järjestelmähakemiston muuttamiseksi pysäytä kaikki käynnissä olevat koneet." + +msgid "Raw" +msgstr "Raaka" diff --git a/src/qt/languages/fr-FR.po b/src/qt/languages/fr-FR.po index 2e1422a08c..42f1a8f406 100644 --- a/src/qt/languages/fr-FR.po +++ b/src/qt/languages/fr-FR.po @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "&Permettre la recompilation" msgid "&Fast forward" -msgstr "" +msgstr "&Avance rapide" msgid "Fast forward" -msgstr "" +msgstr "Avance rapide" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Pour modifier le répertoire système, arrêtez toutes les machines en cours d'exécution." + +msgid "Raw" +msgstr "Brut" diff --git a/src/qt/languages/hr-HR.po b/src/qt/languages/hr-HR.po index b3d9a68f18..32aaf1cf7e 100644 --- a/src/qt/languages/hr-HR.po +++ b/src/qt/languages/hr-HR.po @@ -3018,10 +3018,13 @@ msgid "&Allow recompilation" msgstr "&Omogući rekompilaciju" msgid "&Fast forward" -msgstr "" +msgstr "&Brzo naprijed" msgid "Fast forward" -msgstr "" +msgstr "Brzo naprijed" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Za promjenu sustavskog direktorija zaustavite sve pokrenute strojeve." + +msgid "Raw" +msgstr "Neobrađeni podaci" diff --git a/src/qt/languages/it-IT.po b/src/qt/languages/it-IT.po index f4d16bf860..f46d09159a 100644 --- a/src/qt/languages/it-IT.po +++ b/src/qt/languages/it-IT.po @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "&Permetti ricompilazione" msgid "&Fast forward" -msgstr "" +msgstr "&Avanti veloce" msgid "Fast forward" -msgstr "" +msgstr "Avanti veloce" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Per modificare la directory di sistema, arrestare tutte le macchine in funzione." + +msgid "Raw" +msgstr "Grezzo" diff --git a/src/qt/languages/ja-JP.po b/src/qt/languages/ja-JP.po index 2a7809a47f..027b052047 100644 --- a/src/qt/languages/ja-JP.po +++ b/src/qt/languages/ja-JP.po @@ -3017,10 +3017,13 @@ msgid "&Allow recompilation" msgstr "再コンパイルを許可する(&A)" msgid "&Fast forward" -msgstr "" +msgstr "早送り(&F)" msgid "Fast forward" -msgstr "" +msgstr "早送り" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "システムディレクトリを変更するには、稼働中のマシンをすべて停止してください。" + +msgid "Raw" +msgstr "生" diff --git a/src/qt/languages/ko-KR.po b/src/qt/languages/ko-KR.po index 0318e85f32..cd186260b3 100644 --- a/src/qt/languages/ko-KR.po +++ b/src/qt/languages/ko-KR.po @@ -3010,10 +3010,13 @@ msgid "&Allow recompilation" msgstr "재컴파일 허용(&A)" msgid "&Fast forward" -msgstr "" +msgstr "빠른 전진(&F)" msgid "Fast forward" -msgstr "" +msgstr "빠른 전진" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "시스템 디렉터리를 변경하려면 실행 중인 모든 머신을 중지하십시오." + +msgid "Raw" +msgstr "원본" diff --git a/src/qt/languages/nb-NO.po b/src/qt/languages/nb-NO.po index e31768305d..88679fdd35 100644 --- a/src/qt/languages/nb-NO.po +++ b/src/qt/languages/nb-NO.po @@ -3010,10 +3010,13 @@ msgid "&Allow recompilation" msgstr "&Tillat rekompilering" msgid "&Fast forward" -msgstr "" +msgstr "&Spol fremover" msgid "Fast forward" -msgstr "" +msgstr "Spol fremover" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "For å endre systemkatalogen, stopp alle maskiner som er kjører." + +msgid "Raw" +msgstr "Rå" diff --git a/src/qt/languages/nl-NL.po b/src/qt/languages/nl-NL.po index 3d056a2ea2..63dcd239b3 100644 --- a/src/qt/languages/nl-NL.po +++ b/src/qt/languages/nl-NL.po @@ -3010,10 +3010,13 @@ msgid "&Allow recompilation" msgstr "Recompilatie &toestaan" msgid "&Fast forward" -msgstr "" +msgstr "&Snel vooruitspoelen" msgid "Fast forward" -msgstr "" +msgstr "Snel vooruitspoelen" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Om de systeemmap te wijzigen, moet u alle actieve machines stoppen." + +msgid "Raw" +msgstr "Ruw" diff --git a/src/qt/languages/pl-PL.po b/src/qt/languages/pl-PL.po index 20317c9ecc..e67ada685e 100644 --- a/src/qt/languages/pl-PL.po +++ b/src/qt/languages/pl-PL.po @@ -3017,10 +3017,13 @@ msgid "&Allow recompilation" msgstr "&Zezwól na rekompilację" msgid "&Fast forward" -msgstr "" +msgstr "&Przewiń do przodu" msgid "Fast forward" -msgstr "" +msgstr "Przewiń do przodu" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Aby zmienić katalog systemowy, zatrzymaj wszystkie działające maszyny." + +msgid "Raw" +msgstr "Surowy" diff --git a/src/qt/languages/pt-BR.po b/src/qt/languages/pt-BR.po index 31875d7bab..5ffbc2c72a 100644 --- a/src/qt/languages/pt-BR.po +++ b/src/qt/languages/pt-BR.po @@ -3010,10 +3010,13 @@ msgid "&Allow recompilation" msgstr "&Permitir recompilação" msgid "&Fast forward" -msgstr "" +msgstr "&Avançar rapidamente" msgid "Fast forward" -msgstr "" +msgstr "Avançar rapidamente" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Para alterar o diretório do sistema, pare todas as máquinas em funcionamento." + +msgid "Raw" +msgstr "Bruto" diff --git a/src/qt/languages/pt-PT.po b/src/qt/languages/pt-PT.po index f18eb8f1ab..8f0f55caf4 100644 --- a/src/qt/languages/pt-PT.po +++ b/src/qt/languages/pt-PT.po @@ -3017,10 +3017,13 @@ msgid "&Allow recompilation" msgstr "&Permitir recompilação" msgid "&Fast forward" -msgstr "" +msgstr "&Avançar rapidamente" msgid "Fast forward" -msgstr "" +msgstr "Avançar rapidamente" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Para alterar o diretório do sistema, pare todas as máquinas em funcionamento." + +msgid "Raw" +msgstr "Bruto" diff --git a/src/qt/languages/ru-RU.po b/src/qt/languages/ru-RU.po index 6102dceeda..9ca679356d 100644 --- a/src/qt/languages/ru-RU.po +++ b/src/qt/languages/ru-RU.po @@ -3036,3 +3036,6 @@ msgstr "Перемотка вперёд" msgid "To change the system directory, stop all running machines." msgstr "Чтобы изменить системную папку, остановите все запущенные машины." + +msgid "Raw" +msgstr "Сырой" diff --git a/src/qt/languages/sk-SK.po b/src/qt/languages/sk-SK.po index a112005da8..a5570faebb 100644 --- a/src/qt/languages/sk-SK.po +++ b/src/qt/languages/sk-SK.po @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "&Povoliť rekompiláciu" msgid "&Fast forward" -msgstr "" +msgstr "&Rýchly posun dopredu" msgid "Fast forward" -msgstr "" +msgstr "Rýchly posun dopredu" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Ak chcete zmeniť systémový adresár, zastavte všetky bežiace stroje." + +msgid "Raw" +msgstr "Surový" diff --git a/src/qt/languages/sl-SI.po b/src/qt/languages/sl-SI.po index 64cc6e7eb3..dfe0acbcde 100644 --- a/src/qt/languages/sl-SI.po +++ b/src/qt/languages/sl-SI.po @@ -3018,10 +3018,13 @@ msgid "&Allow recompilation" msgstr "&Dovoli prevajanje" msgid "&Fast forward" -msgstr "" +msgstr "&Hitro previj" msgid "Fast forward" -msgstr "" +msgstr "Hitro previj" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Da bi spremenili sistemski imenik, ustavite vse naprave, ki se izvajajo." + +msgid "Raw" +msgstr "Neobdelan" diff --git a/src/qt/languages/sv-SE.po b/src/qt/languages/sv-SE.po index f492359191..eb76331684 100644 --- a/src/qt/languages/sv-SE.po +++ b/src/qt/languages/sv-SE.po @@ -3010,10 +3010,13 @@ msgid "&Allow recompilation" msgstr "&Tillåt omkompilering" msgid "&Fast forward" -msgstr "" +msgstr "&Spola fram" msgid "Fast forward" -msgstr "" +msgstr "Spola fram" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "ör att ändra systemkatalogen, stoppa alla maskiner som är körs." + +msgid "Raw" +msgstr "Rå" diff --git a/src/qt/languages/tr-TR.po b/src/qt/languages/tr-TR.po index a40e07e4b4..510fd82f3c 100644 --- a/src/qt/languages/tr-TR.po +++ b/src/qt/languages/tr-TR.po @@ -3023,3 +3023,6 @@ msgstr "İleri sar" msgid "To change the system directory, stop all running machines." msgstr "Sistem dizinini değiştirmek için tüm çalışan makineleri durdurun." + +msgid "Raw" +msgstr "Ham" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 7fd0d0b332..d1964e647f 100644 --- a/src/qt/languages/uk-UA.po +++ b/src/qt/languages/uk-UA.po @@ -3018,10 +3018,13 @@ msgid "&Allow recompilation" msgstr "&Дозволити рекомпіляцію" msgid "&Fast forward" -msgstr "" +msgstr "&Перемотай вперед" msgid "Fast forward" -msgstr "" +msgstr "Перемотай вперед" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Щоб змінити системний каталог, зупиніть усі машини, що працюють." + +msgid "Raw" +msgstr "Сирий" diff --git a/src/qt/languages/vi-VN.po b/src/qt/languages/vi-VN.po index b2c7491a10..64d00e2103 100644 --- a/src/qt/languages/vi-VN.po +++ b/src/qt/languages/vi-VN.po @@ -3010,10 +3010,13 @@ msgid "&Allow recompilation" msgstr "&Cho phép biên dịch lại" msgid "&Fast forward" -msgstr "" +msgstr "&Chuyển nhanh băng" msgid "Fast forward" -msgstr "" +msgstr "Chuyển nhanh băng" msgid "To change the system directory, stop all running machines." -msgstr "" +msgstr "Để thay đổi thư mục hệ thống, hãy tắt tất cả các máy đang chạy." + +msgid "Raw" +msgstr "Thô" diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index c922e207bd..7e98480cd9 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -3024,3 +3024,6 @@ msgstr "快进" msgid "To change the system directory, stop all running machines." msgstr "请在变更系统目录前关闭所有正在运行的虚拟机。" + +msgid "Raw" +msgstr "原始" diff --git a/src/qt/languages/zh-TW.po b/src/qt/languages/zh-TW.po index 0bdcd215a0..78365a9113 100644 --- a/src/qt/languages/zh-TW.po +++ b/src/qt/languages/zh-TW.po @@ -3024,3 +3024,6 @@ msgstr "快轉" msgid "To change the system directory, stop all running machines." msgstr "欲變更系統目錄,請先停止全部運行中的機器。" + +msgid "Raw" +msgstr "原始" diff --git a/src/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index f2268cd0f0..77271ed8d7 100644 --- a/src/sound/snd_lpt_dac.c +++ b/src/sound/snd_lpt_dac.c @@ -93,7 +93,7 @@ dac_init(UNUSED(const device_t *info)) { lpt_dac_t *lpt_dac = calloc(1, sizeof(lpt_dac_t)); - lpt_dac->lpt = lpt_attach(info->local & 0xf, dac_write_data, dac_write_ctrl, dac_strobe, dac_read_status, NULL, NULL, NULL, lpt_dac); + lpt_dac->lpt = lpt_attach(dac_write_data, dac_write_ctrl, dac_strobe, dac_read_status, NULL, NULL, NULL, lpt_dac); sound_add_handler(dac_get_buffer, lpt_dac); diff --git a/src/sound/snd_lpt_dss.c b/src/sound/snd_lpt_dss.c index 2581d78732..6fac66b6e8 100644 --- a/src/sound/snd_lpt_dss.c +++ b/src/sound/snd_lpt_dss.c @@ -118,7 +118,7 @@ dss_init(UNUSED(const device_t *info)) { dss_t *dss = calloc(1, sizeof(dss_t)); - dss->lpt = lpt_attach(info->local & 0xf, dss_write_data, dss_write_ctrl, NULL, dss_read_status, NULL, NULL, NULL, dss); + dss->lpt = lpt_attach(dss_write_data, dss_write_ctrl, NULL, dss_read_status, NULL, NULL, NULL, dss); sound_add_handler(dss_get_buffer, dss); timer_add(&dss->timer, dss_callback, dss, 1); From 7bbbf489135c6ec5d79f534beb79a6cb2040dcda Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 27 Jan 2026 18:58:39 +0100 Subject: [PATCH 53/58] PostScript and PCL printers: Do not attempt to load the library if the language is set to raw. --- src/printer/prt_ps.c | 64 ++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 29 deletions(-) diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 77ecf0a5fb..29ae78feb8 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -530,25 +530,28 @@ ps_init(const device_t *info) dev->lpt = lpt_attach(ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); dev->lang = device_get_config_int("language"); - /* Try loading the DLL. */ - ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); + if (dev->lang != LANG_RAW) { + /* Try loading the DLL. */ + ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); #ifdef PATH_GHOSTSCRIPT_DLL_ALT1 - if (ghostscript_handle == NULL) { - ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT1, ghostscript_imports); + if (ghostscript_handle == NULL) { + ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT1, ghostscript_imports); # ifdef PATH_GHOSTSCRIPT_DLL_ALT2 - if (ghostscript_handle == NULL) - ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT2, ghostscript_imports); + if (ghostscript_handle == NULL) + ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT2, ghostscript_imports); # endif - } + } #endif - if (ghostscript_handle == NULL) { - ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_GHOSTSCRIPT_ERROR_TITLE), plat_get_string(STRING_GHOSTSCRIPT_ERROR_DESC)); - } else { - if (gsapi_revision(&rev, sizeof(rev)) == 0) { - pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); - } else { - dynld_close(ghostscript_handle); - ghostscript_handle = NULL; + + if (ghostscript_handle == NULL) { + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_GHOSTSCRIPT_ERROR_TITLE), plat_get_string(STRING_GHOSTSCRIPT_ERROR_DESC)); + } else { + if (gsapi_revision(&rev, sizeof(rev)) == 0) { + pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); + } else { + dynld_close(ghostscript_handle); + ghostscript_handle = NULL; + } } } @@ -579,25 +582,28 @@ pcl_init(const device_t *info) dev->lpt = lpt_attach(ps_write_data, ps_write_ctrl, ps_strobe, ps_read_status, NULL, NULL, NULL, dev); dev->lang = device_get_config_int("language"); - /* Try loading the DLL. */ - ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL, ghostscript_imports); + if (dev->lang != LANG_RAW) { + /* Try loading the DLL. */ + ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL, ghostscript_imports); #ifdef PATH_GHOSTPCL_DLL_ALT1 - if (ghostscript_handle == NULL) { - ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT1, ghostscript_imports); + if (ghostscript_handle == NULL) { + ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT1, ghostscript_imports); # ifdef PATH_GHOSTPCL_DLL_ALT2 - if (ghostscript_handle == NULL) - ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT2, ghostscript_imports); + if (ghostscript_handle == NULL) + ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL_ALT2, ghostscript_imports); # endif - } + } #endif - if (ghostscript_handle == NULL) { - ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_GHOSTPCL_ERROR_TITLE), plat_get_string(STRING_GHOSTPCL_ERROR_DESC)); - } else { - if (gsapi_revision(&rev, sizeof(rev)) == 0) { - pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); + + if (ghostscript_handle == NULL) { + ui_msgbox_header(MBX_ERROR, plat_get_string(STRING_GHOSTPCL_ERROR_TITLE), plat_get_string(STRING_GHOSTPCL_ERROR_DESC)); } else { - dynld_close(ghostscript_handle); - ghostscript_handle = NULL; + if (gsapi_revision(&rev, sizeof(rev)) == 0) { + pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); + } else { + dynld_close(ghostscript_handle); + ghostscript_handle = NULL; + } } } From 2a00f72a6fd0e53ecb0192cb876c258d65e39a75 Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Wed, 28 Jan 2026 13:38:26 +0800 Subject: [PATCH 54/58] VTech Laser Turbo XT: add older BIOS 1.08 --- src/chipset/laserxt.c | 31 +++++++++++++++++++++++++++++++ src/include/86box/machine.h | 3 +++ src/machine/m_xt.c | 13 ++++++++++--- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/chipset/laserxt.c b/src/chipset/laserxt.c index a5308e2f01..bf2636b917 100644 --- a/src/chipset/laserxt.c +++ b/src/chipset/laserxt.c @@ -296,6 +296,37 @@ lxt_init(const device_t *info) } static const device_config_t laserxt_config[] = { + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "laserxt_126", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "1.08", + .internal_name = "laserxt_108", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/ltxt/ltxt-v1.08.bin", "" } + }, + { + .name = "1.26", + .internal_name = "laserxt_126", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 0, + .size = 8192, + .files = { "roms/machines/ltxt/27c64.bin", "" } + }, + { .files_no = 0 } + } + }, { .name = "ems_1_base", .description = "EMS 1 Address", diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 6ab3883c8a..793aee6fe1 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1479,6 +1479,9 @@ extern int machine_xt_to16_init(const machine_t *); extern const device_t vendex_device; #endif extern int machine_xt_vendex_init(const machine_t *); +#ifdef EMU_DEVICE_H +extern const device_t laserxt_device; +#endif extern int machine_xt_laserxt_init(const machine_t *); extern int machine_xt_znic_init(const machine_t *); extern int machine_xt_z151_init(const machine_t *); diff --git a/src/machine/m_xt.c b/src/machine/m_xt.c index 81c9eba728..6da39d9971 100644 --- a/src/machine/m_xt.c +++ b/src/machine/m_xt.c @@ -1884,10 +1884,17 @@ machine_xt_laserxt_common_init(const machine_t *model, int is_lxt3) int machine_xt_laserxt_init(const machine_t *model) { - int ret; + int ret = 0; + const char *fn; - ret = bios_load_linear("roms/machines/ltxt/27c64.bin", - 0x000fe000, 8192, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; + + device_context(model->device); + fn = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); + ret = bios_load_linear(fn, 0x000fe000, 8192, 0); + device_context_restore(); if (bios_only || !ret) return ret; From 715a6cf4cda69eabeeae42813863ebe79df4204e Mon Sep 17 00:00:00 2001 From: Bozo Scum Date: Wed, 28 Jan 2026 13:45:15 +0800 Subject: [PATCH 55/58] makes Victor V86P BIOS versions selectable --- src/include/86box/machine.h | 3 ++ src/machine/m_v86p.c | 102 +++++++++++++++++++++++++++++------- src/machine/machine_table.c | 2 +- 3 files changed, 88 insertions(+), 19 deletions(-) diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index 793aee6fe1..caf929c194 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -1408,6 +1408,9 @@ extern const device_t tandy_1000sl_video_device; extern int machine_tandy1000sl2_init(const machine_t *); /* m_v86p.c */ +#ifdef EMU_DEVICE_H +extern const device_t v86p_device; +#endif extern int machine_v86p_init(const machine_t *); /* m_xt.c */ diff --git a/src/machine/m_v86p.c b/src/machine/m_v86p.c index 1265173458..d30d9c8a6e 100644 --- a/src/machine/m_v86p.c +++ b/src/machine/m_v86p.c @@ -48,35 +48,101 @@ #include <86box/sio.h> #include <86box/video.h> +static const device_config_t v86p_config[] = { + // clang-format off + { + .name = "bios", + .description = "BIOS Version", + .type = CONFIG_BIOS, + .default_string = "v86p_122089", + .default_int = 0, + .file_filter = NULL, + .spinner = { 0 }, + .selection = { { 0 } }, + .bios = { + { + .name = "12/20/89", + .internal_name = "v86p_122089", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_122089_Even.rom", + "roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_122089_Odd.rom", + "" } + }, + { + .name = "09/04/89", + .internal_name = "v86p_090489", + .bios_type = BIOS_NORMAL, + .files_no = 2, + .local = 0, + .size = 65536, + .files = { "roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_090489_Even.rom", + "roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_090489_Odd.rom", + "" } + }, + { + .name = "09/04/89 (Alt)", + .internal_name = "v86p_jvernet", + .bios_type = BIOS_NORMAL, + .files_no = 1, + .local = 1, + .size = 65536, + .files = { "roms/machines/v86p/V86P.ROM", + "" } + }, + { .files_no = 0 } + } + }, + { .name = "", .description = "", .type = CONFIG_END } + // clang-format on +}; + +const device_t v86p_device = { + .name = "Victor V86P", + .internal_name = "v86p_device", + .flags = 0, + .local = 0, + .init = NULL, + .close = NULL, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = v86p_config +}; + int machine_v86p_init(const machine_t *model) { - int ret; - int rom_id = 0; + int ret = 0; + int files_no = 0; + int local = 0; + const char *fn1, *fn2; - ret = bios_load_interleavedr("roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_122089_Even.rom", - "roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_122089_Odd.rom", - 0x000f8000, 65536, 0); + /* No ROMs available. */ + if (!device_available(model->device)) + return ret; - if (!ret) { - /* Try an older version of the BIOS. */ - rom_id = 1; - ret = bios_load_interleavedr("roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_090489_Even.rom", - "roms/machines/v86p/INTEL8086AWD_BIOS_S3.1_V86P_090489_Odd.rom", - 0x000f8000, 65536, 0); - } + device_context(model->device); + files_no = device_get_bios_num_files(model->device, device_get_config_bios("bios")); + local = device_get_bios_local(model->device, device_get_config_bios("bios")); + fn1 = device_get_bios_file(model->device, device_get_config_bios("bios"), 0); - if (!ret) { - /* Try JVERNET's BIOS. */ - rom_id = 2; - ret = bios_load_linear("roms/machines/v86p/V86P.ROM", - 0x000f0000, 65536, 0); + if (files_no > 1) + { + fn2 = device_get_bios_file(model->device, device_get_config_bios("bios"), 1); + ret = bios_load_interleavedr(fn1, fn2, 0x000f8000, 65536, 0); } + else + ret = bios_load_linear(fn1, 0x000f0000, 65536, 0); + device_context_restore(); if (bios_only || !ret) return ret; - if (rom_id == 2) + if (local > 0) video_load_font("roms/machines/v86p/V86P.FON", FONT_FORMAT_PC1512_T1000, LOAD_FONT_NO_OFFSET); else video_load_font("roms/machines/v86p/v86pfont.rom", FONT_FORMAT_PC1512_T1000, LOAD_FONT_NO_OFFSET); diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index e113f3fe04..762c4410ec 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2982,7 +2982,7 @@ const machine_t machines[] = { .kbc_p1 = 0xff, .gpio = 0xffffffff, .gpio_acpi = 0xffffffff, - .device = NULL, + .device = &v86p_device, .kbd_device = NULL, .fdc_device = NULL, .sio_device = NULL, From 85599deeb18a2410fc06d766fba12fafe282e5dc Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 Jan 2026 07:44:12 +0100 Subject: [PATCH 56/58] Ports Settings: Add lpt_device_available() check. --- src/qt/qt_settingsports.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/qt/qt_settingsports.cpp b/src/qt/qt_settingsports.cpp index b1155629db..232822201a 100644 --- a/src/qt/qt_settingsports.cpp +++ b/src/qt/qt_settingsports.cpp @@ -138,13 +138,15 @@ SettingsPorts::onCurrentMachineChanged(int machineId) if (lptName == nullptr) break; - const QString name = tr(lptName); + if (lpt_device_available(c)) { + const QString name = tr(lptName); - for (uint8_t i = 0; i < PARALLEL_MAX; ++i) { - int row = Models::AddEntry(models[i], name, c); + for (uint8_t i = 0; i < PARALLEL_MAX; ++i) { + int row = Models::AddEntry(models[i], name, c); - if (c == lpt_ports[i].device) - selectedRows[i] = row - removeRows_[i]; + if (c == lpt_ports[i].device) + selectedRows[i] = row - removeRows_[i]; + } } c++; From 72ea51332deefc227e5912540329fa7815a588cc Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 Jan 2026 08:45:05 +0100 Subject: [PATCH 57/58] Use the 808x rewrite from the 808x_rewrite branch as the NEC Vx0 rewrite, as it's good enough for that (it even approximates the NEC Vx0 timings unlike what was there before which did not even remotely attempt to). --- src/cpu/808x.c | 566 +---- src/cpu/CMakeLists.txt | 2 + src/cpu/cpu.c | 2 + src/cpu/cpu.h | 3 + src/cpu/vx0.c | 4783 ++++++++++++++++++++++++++++++++++++++++ src/cpu/vx0_biu.c | 1152 ++++++++++ src/cpu/vx0_biu.h | 116 + src/cpu/x86.c | 8 +- src/cpu/x86.h | 2 + src/cpu/x87_ops.h | 4 + src/cpu/x87_ops_misc.h | 4 + src/cpu/x87_ops_sf.h | 4 + 12 files changed, 6114 insertions(+), 532 deletions(-) create mode 100644 src/cpu/vx0.c create mode 100644 src/cpu/vx0_biu.c create mode 100644 src/cpu/vx0_biu.h diff --git a/src/cpu/808x.c b/src/cpu/808x.c index 4e2e830d0e..7908160e80 100644 --- a/src/cpu/808x.c +++ b/src/cpu/808x.c @@ -51,7 +51,8 @@ uint32_t custom_nmi_vector = 0x00000000; static uint8_t pfq[6]; /* Variables to aid with the prefetch queue operation. */ -static int biu_cycles = 0, pfq_pos = 0; +static int biu_cycles = 0; +int pfq_pos = 0; /* The IP equivalent of the current prefetch queue position. */ static uint16_t pfq_ip; @@ -66,7 +67,7 @@ static int cpu_alu_op, pfq_size; static uint32_t cpu_src = 0, cpu_dest = 0; static uint32_t cpu_data = 0; -static uint16_t last_addr = 0x0000; +uint16_t last_addr = 0x0000; static uint32_t *ovr_seg = NULL; static int prefetching = 1, completed = 1; @@ -204,67 +205,12 @@ prefetch_queue_get_size(void) } static void set_if(int cond); -void -sync_from_i8080(void) -{ - AL = emulated_processor.a; - BH = emulated_processor.h; - BL = emulated_processor.l; - CH = emulated_processor.b; - CL = emulated_processor.c; - DH = emulated_processor.d; - DL = emulated_processor.e; - BP = emulated_processor.sp; - - cpu_state.pc = emulated_processor.pc; - cpu_state.flags &= 0xFF00; - cpu_state.flags |= emulated_processor.sf << 7; - cpu_state.flags |= emulated_processor.zf << 6; - cpu_state.flags |= emulated_processor.hf << 4; - cpu_state.flags |= emulated_processor.pf << 2; - cpu_state.flags |= 1 << 1; - cpu_state.flags |= emulated_processor.cf << 0; - set_if(emulated_processor.iff); -} - -void -sync_to_i8080(void) -{ - if (!is_nec) - return; - emulated_processor.a = AL; - emulated_processor.h = BH; - emulated_processor.l = BL; - emulated_processor.b = CH; - emulated_processor.c = CL; - emulated_processor.d = DH; - emulated_processor.e = DL; - emulated_processor.sp = BP; - emulated_processor.pc = cpu_state.pc; - emulated_processor.iff = !!(cpu_state.flags & I_FLAG); - - emulated_processor.sf = (cpu_state.flags >> 7) & 1; - emulated_processor.zf = (cpu_state.flags >> 6) & 1; - emulated_processor.hf = (cpu_state.flags >> 4) & 1; - emulated_processor.pf = (cpu_state.flags >> 2) & 1; - emulated_processor.cf = (cpu_state.flags >> 0) & 1; - - emulated_processor.interrupt_delay = noint; -} - - uint16_t get_last_addr(void) { return last_addr; } -static void -clock_start(void) -{ - cycdiff = cycles; -} - static void clock_end(void) { @@ -293,7 +239,7 @@ fetch_and_bus(int c, int bus) pfq_add(c, !bus); if (bus < 2) { clock_end(); - clock_start(); + cycdiff = cycles; } } @@ -412,7 +358,7 @@ readmemw(uint32_t s, uint16_t a) else { wait_cycs(4, 1); ret = read_mem_b(s + a); - ret |= read_mem_b(s + ((is186 && !is_nec) ? (a + 1) : (a + 1) & 0xffff)) << 8; + ret |= read_mem_b(s + (is186 ? (a + 1) : (a + 1) & 0xffff)) << 8; } return ret; @@ -484,7 +430,7 @@ writememw(uint32_t s, uint32_t a, uint16_t v) else { write_mem_b(addr, v & 0xff); wait_cycs(4, 1); - addr = s + ((is186 && !is_nec) ? (a + 1) : ((a + 1) & 0xffff)); + addr = s + (is186 ? (a + 1) : ((a + 1) & 0xffff)); write_mem_b(addr, v >> 8); } @@ -693,8 +639,6 @@ reset_808x(int hard) load_cs(0xFFFF); cpu_state.pc = 0; - if (is_nec) - cpu_state.flags |= MD_FLAG; rammask = 0xfffff; prefetching = 1; @@ -929,7 +873,7 @@ seteaq(uint64_t val) static void push(uint16_t *val) { - if ((is186 && !is_nec) && (SP == 1)) { + if (is186 && (SP == 1)) { writememw(ss - 1, 0, *val); SP = cpu_state.eaaddr = 0xFFFF; return; @@ -1085,11 +1029,6 @@ interrupt(uint16_t addr) uint16_t new_cs, new_ip; uint16_t tempf; - if (!(cpu_state.flags & MD_FLAG) && is_nec) { - sync_from_i8080(); - x808x_log("CALLN/INT#/NMI#\n"); - } - addr <<= 2; cpu_state.eaaddr = addr; old_cs = CS; @@ -1103,11 +1042,9 @@ interrupt(uint16_t addr) pfq_clear(); ovr_seg = NULL; access(39, 16); - tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); + tempf = cpu_state.flags & 0x0fd7; push(&tempf); cpu_state.flags &= ~(I_FLAG | T_FLAG); - if (is_nec) - cpu_state.flags |= MD_FLAG; access(40, 16); push(&old_cs); old_ip = cpu_state.pc; @@ -1118,71 +1055,6 @@ interrupt(uint16_t addr) push(&old_ip); } -/* Ditto, but for breaking into emulation mode. */ -static void -interrupt_brkem(uint16_t addr) -{ - uint16_t old_cs, old_ip; - uint16_t new_cs, new_ip; - uint16_t tempf; - - addr <<= 2; - cpu_state.eaaddr = addr; - old_cs = CS; - access(5, 16); - new_ip = readmemw(0, cpu_state.eaaddr); - wait_cycs(1, 0); - cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; - access(6, 16); - new_cs = readmemw(0, cpu_state.eaaddr); - prefetching = 0; - pfq_clear(); - ovr_seg = NULL; - access(39, 16); - tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); - push(&tempf); - cpu_state.flags &= ~(MD_FLAG); - cpu_md_write_disable = 0; - access(40, 16); - push(&old_cs); - old_ip = cpu_state.pc; - load_cs(new_cs); - access(68, 16); - set_ip(new_ip); - access(41, 16); - push(&old_ip); - sync_to_i8080(); - x808x_log("BRKEM mode\n"); -} - -void -retem_i8080(void) -{ - sync_from_i8080(); - - prefetching = 0; - pfq_clear(); - - set_ip(pop()); - load_cs(pop()); - cpu_state.flags = pop(); - - emulated_processor.iff = !!(cpu_state.flags & I_FLAG); - - cpu_md_write_disable = 1; - - noint = 1; - nmi_enable = 1; - - x808x_log("RETEM mode\n"); -} - -void -interrupt_808x(uint16_t addr) -{ - interrupt(addr); -} - static void custom_nmi(void) { @@ -1190,11 +1062,6 @@ custom_nmi(void) uint16_t new_cs, new_ip; uint16_t tempf; - if (!(cpu_state.flags & MD_FLAG) && is_nec) { - sync_from_i8080(); - pclog("NMI# (CUTSOM)\n"); - } - cpu_state.eaaddr = 0x0002; old_cs = CS; access(5, 16); @@ -1209,11 +1076,9 @@ custom_nmi(void) pfq_clear(); ovr_seg = NULL; access(39, 16); - tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); + tempf = cpu_state.flags & 0x0fd7; push(&tempf); cpu_state.flags &= ~(I_FLAG | T_FLAG); - if (is_nec) - cpu_state.flags |= MD_FLAG; access(40, 16); push(&old_cs); old_ip = cpu_state.pc; @@ -1225,10 +1090,10 @@ custom_nmi(void) } static int -irq_pending(int nec_hlt) +irq_pending(void) { uint8_t temp; - int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt; + int i_flag = (cpu_state.flags & I_FLAG); temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || (i_flag && pic.int_pending && !noint); @@ -1236,12 +1101,12 @@ irq_pending(int nec_hlt) } static void -check_interrupts(int nec_hlt) +check_interrupts(void) { int temp; - int i_flag = (cpu_state.flags & I_FLAG) || nec_hlt; + int i_flag = (cpu_state.flags & I_FLAG); - if (irq_pending(nec_hlt)) { + if (irq_pending()) { if ((cpu_state.flags & T_FLAG) && !(noint & 1)) { interrupt(1); return; @@ -1290,13 +1155,10 @@ rep_action(int bits) return 0; wait_cycs(2, 0); t = CX; - if (irq_pending(0) && (repeating != 0)) { + if (irq_pending() && (repeating != 0)) { access(71, bits); pfq_clear(); - if (is_nec && (ovr_seg != NULL)) - set_ip(cpu_state.pc - 3); - else - set_ip(cpu_state.pc - 2); + set_ip(cpu_state.pc - 2); t = 0; } if (t == 0) { @@ -1919,32 +1781,16 @@ void execx86(int cycs) { uint8_t temp = 0, temp2, old_af, nests; - uint8_t temp_val, temp_al, bit, handled = 0; - uint8_t odd, zero, nibbles_count, destcmp; - uint8_t destbyte, srcbyte, nibble_result, bit_length; - uint8_t bit_offset; - int8_t nibble_result_s; - uint16_t addr, tempw, new_cs, new_ip; + uint16_t addr, tempw, new_cs, new_ip, handled = 0; uint16_t tempw_int, size, tempbp, lowbound; - uint16_t highbound, regval, orig_sp, wordtopush; - uint16_t immediate, old_flags; + uint16_t highbound, regval, orig_sp, wordtopush, immediate; int bits; - uint32_t dest_seg, i, carry, nibble; - uint32_t srcseg, byteaddr; + uint32_t dest_seg; cycles += cycs; while (cycles > 0) { - clock_start(); - - if (is_nec && !(cpu_state.flags & MD_FLAG)) { - i8080_step(&emulated_processor); - set_if(emulated_processor.iff); - cycles -= emulated_processor.cyc; - emulated_processor.cyc = 0; - completed = 1; - goto exec_completed; - } + cycdiff = cycles; if (!repeating) { cpu_state.oldpc = cpu_state.pc; @@ -2004,18 +1850,6 @@ execx86(int cycs) handled = 1; break; - case 0x64: - case 0x65: - if (is_nec) { - /* REPC/REPNC */ - wait_cycs(1, 0); - in_rep = (opcode == 0x64 ? 1 : 2); - rep_c_flag = 1; - completed = 0; - handled = 1; - } - break; - case 0x68: wordtopush = pfq_fetchw(); wait_cycs(1, 0); @@ -2111,7 +1945,6 @@ execx86(int cycs) tempw_int = 0; size = pfq_fetchw(); nests = pfq_fetchb(); - i = 0; push(&BP); tempw_int = SP; @@ -2141,8 +1974,7 @@ execx86(int cycs) wait_cycs((cpu_mod != 3) ? 9 : 6, 0); - if (!is_nec) - cpu_src &= 0x1F; + cpu_src &= 0x1F; while (cpu_src != 0) { cpu_dest = cpu_data; oldc = cpu_state.flags & C_FLAG; @@ -2239,299 +2071,6 @@ execx86(int cycs) case 0x0F: case 0x17: case 0x1F: /* POP seg */ - if (is_nec && (opcode == 0x0F)) { - uint8_t orig_opcode = opcode; - opcode = pfq_fetchb(); - switch (opcode) { - case 0x28: /* ROL4 r/m */ - do_mod_rm(); - wait_cycs(21, 0); - - temp_val = geteab(); - temp_al = AL; - - temp_al &= 0xF; - temp_al |= (temp_val & 0xF0); - temp_val = (temp_al & 0xF) | ((temp_val & 0xF) << 4); - temp_al >>= 4; - temp_al &= 0xF; - seteab(temp_val); - AL = temp_al; - - handled = 1; - break; - - case 0x2a: /* ROR4 r/m */ - do_mod_rm(); - wait_cycs(21, 0); - - temp_val = geteab(); - temp_al = AL; - - AL = temp_val & 0xF; - temp_val = (temp_val >> 4) | ((temp_al & 0xF) << 4); - - seteab(temp_val); - - handled = 1; - break; - - case 0x10: /* TEST1 r8/m8, CL*/ - case 0x11: /* TEST1 r16/m16, CL*/ - case 0x18: /* TEST1 r8/m8, imm3 */ - case 0x19: /* TEST1 r16/m16, imm4 */ - bits = 8 << (opcode & 0x1); - do_mod_rm(); - wait_cycs(3, 0); - - bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); - bit &= ((1 << (3 + (opcode & 0x1))) - 1); - read_ea(0, bits); - - set_zf_ex(!(cpu_data & (1 << bit))); - cpu_state.flags &= ~(V_FLAG | C_FLAG); - - handled = 1; - break; - - case 0x16: /* NOT1 r8/m8, CL*/ - case 0x17: /* NOT1 r16/m16, CL*/ - case 0x1e: /* NOT1 r8/m8, imm3 */ - case 0x1f: /* NOT1 r16/m16, imm4 */ - bits = 8 << (opcode & 0x1); - do_mod_rm(); - wait_cycs(3, 0); - - bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); - bit &= ((1 << (3 + (opcode & 0x1))) - 1); - read_ea(0, bits); - - if (bits == 8) - seteab((cpu_data & 0xFF) ^ (1 << bit)); - else - seteaw((cpu_data & 0xFFFF) ^ (1 << bit)); - - handled = 1; - break; - - case 0x14: /* SET1 r8/m8, CL*/ - case 0x15: /* SET1 r16/m16, CL*/ - case 0x1c: /* SET1 r8/m8, imm3 */ - case 0x1d: /* SET1 r16/m16, imm4 */ - bits = 8 << (opcode & 0x1); - do_mod_rm(); - wait_cycs(3, 0); - - bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); - bit &= ((1 << (3 + (opcode & 0x1))) - 1); - read_ea(0, bits); - - if (bits == 8) - seteab((cpu_data & 0xFF) | (1 << bit)); - else - seteaw((cpu_data & 0xFFFF) | (1 << bit)); - - handled = 1; - break; - - case 0x12: /* CLR1 r8/m8, CL*/ - case 0x13: /* CLR1 r16/m16, CL*/ - case 0x1a: /* CLR1 r8/m8, imm3 */ - case 0x1b: /* CLR1 r16/m16, imm4 */ - bits = 8 << (opcode & 0x1); - do_mod_rm(); - wait_cycs(3, 0); - - bit = (opcode & 0x8) ? (pfq_fetchb()) : (CL); - bit &= ((1 << (3 + (opcode & 0x1))) - 1); - read_ea(0, bits); - - if (bits == 8) - seteab((cpu_data & 0xFF) & ~(1 << bit)); - else - seteaw((cpu_data & 0xFFFF) & ~(1 << bit)); - - handled = 1; - break; - - case 0x20: /* ADD4S */ - odd = !!(CL % 2); - zero = 1; - nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; - - wait_cycs(5, 0); - for (i = 0; i < ((nibbles_count / 2) + odd); i++) { - wait_cycs(19, 0); - destcmp = read_mem_b((es) + DI + i); - for (nibble = 0; nibble < 2; nibble++) { - destbyte = destcmp >> (nibble ? 4 : 0); - srcbyte = read_mem_b(srcseg + SI + i) >> (nibble ? 4 : 0); - destbyte &= 0xF; - srcbyte &= 0xF; - nibble_result = (i == (nibbles_count / 2) && nibble == 1) ? (destbyte + carry) : ((uint8_t) (destbyte)) + ((uint8_t) (srcbyte)) + ((uint32_t) carry); - carry = 0; - while (nibble_result >= 10) { - nibble_result -= 10; - carry++; - } - if (zero != 0 || (i == (nibbles_count / 2) && nibble == 1)) - zero = (nibble_result == 0); - destcmp = ((destcmp & (nibble ? 0x0F : 0xF0)) | (nibble_result << (4 * nibble))); - } - write_mem_b(es + DI + i, destcmp); - } - set_cf(!!carry); - set_zf(!!zero); - handled = 1; - break; - - case 0x22: /* SUB4S */ - odd = !!(CL % 2); - zero = 1; - nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; - - wait_cycs(5, 0); - for (i = 0; i < ((nibbles_count / 2) + odd); i++) { - wait_cycs(19, 0); - destcmp = read_mem_b((es) + DI + i); - for (nibble = 0; nibble < 2; nibble++) { - destbyte = destcmp >> (nibble ? 4 : 0); - srcbyte = read_mem_b(srcseg + SI + i) >> (nibble ? 4 : 0); - destbyte &= 0xF; - srcbyte &= 0xF; - nibble_result_s = (i == (nibbles_count / 2) && nibble == 1) ? ((int8_t) destbyte - (int8_t) carry) : ((int8_t) (destbyte)) - ((int8_t) (srcbyte)) - ((int8_t) carry); - carry = 0; - while (nibble_result_s < 0) { - nibble_result_s += 10; - carry++; - } - if (zero != 0 || (i == (nibbles_count / 2) && nibble == 1)) - zero = (nibble_result_s == 0); - destcmp = ((destcmp & (nibble ? 0x0F : 0xF0)) | (nibble_result_s << (4 * nibble))); - } - write_mem_b(es + DI + i, destcmp); - } - set_cf(!!carry); - set_zf(!!zero); - handled = 1; - break; - - case 0x26: /* CMP4S */ - odd = !!(CL % 2); - zero = 1; - nibbles_count = CL - odd; - i = 0; - carry = 0; - nibble = 0; - srcseg = ovr_seg ? *ovr_seg : ds; - - wait_cycs(5, 0); - for (i = 0; i < ((nibbles_count / 2) + odd); i++) { - wait_cycs(19, 0); - destcmp = read_mem_b((es) + DI + i); - for (nibble = 0; nibble < 2; nibble++) { - destbyte = destcmp >> (nibble ? 4 : 0); - srcbyte = read_mem_b(srcseg + SI + i) >> (nibble ? 4 : 0); - destbyte &= 0xF; - srcbyte &= 0xF; - nibble_result_s = ((int8_t) (destbyte)) - ((int8_t) (srcbyte)) - ((int8_t) carry); - carry = 0; - while (nibble_result_s < 0) { - nibble_result_s += 10; - carry++; - } - if (zero != 0 || (i == (nibbles_count / 2) && nibble == 1)) - zero = (nibble_result_s == 0); - destcmp = ((destcmp & (nibble ? 0x0F : 0xF0)) | (nibble_result_s << (4 * nibble))); - } - } - set_cf(!!carry); - set_zf(!!zero); - handled = 1; - break; - - case 0x31: /* INS reg1, reg2 */ - case 0x39: /* INS reg8, imm4 */ - do_mod_rm(); - wait_cycs(1, 0); - - bit_length = ((opcode & 0x8) ? (pfq_fetchb() & 0xF) : (getr8(cpu_reg) & 0xF)) + 1; - bit_offset = getr8(cpu_rm) & 0xF; - byteaddr = (es) + DI; - i = 0; - - if (bit_offset >= 8) { - DI++; - byteaddr++; - bit_offset -= 8; - } - for (i = 0; i < bit_length; i++) { - byteaddr = (es) + DI; - writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << (bit_offset))) | ((!!(AX & (1 << i))) << bit_offset)); - bit_offset++; - if (bit_offset == 8) { - DI++; - bit_offset = 0; - } - } - setr8(cpu_rm, bit_offset); - - handled = 1; - break; - - case 0x33: /* EXT reg1, reg2 */ - case 0x3b: /* EXT reg8, imm4 */ - do_mod_rm(); - wait_cycs(1, 0); - - bit_length = ((opcode & 0x8) ? (pfq_fetchb() & 0xF) : (getr8(cpu_reg) & 0xF)) + 1; - bit_offset = getr8(cpu_rm) & 0xF; - byteaddr = (ds) + SI; - i = 0; - - if (bit_offset >= 8) { - SI++; - byteaddr++; - bit_offset -= 8; - } - - AX = 0; - for (i = 0; i < bit_length; i++) { - byteaddr = (ds) + SI; - AX |= (!!(readmemb(byteaddr) & (1 << bit_offset))) << i; - bit_offset++; - if (bit_offset == 8) { - SI++; - bit_offset = 0; - } - } - setr8(cpu_rm, bit_offset); - - handled = 1; - break; - - case 0xFF: /* BRKEM */ - interrupt_brkem(pfq_fetchb()); - handled = 1; - break; - - default: - opcode = orig_opcode; - cpu_state.pc--; - break; - } - } else - handled = 0; - if (handled) - break; access(22, 16); if (opcode == 0x0F) { load_cs(pop()); @@ -3019,28 +2558,21 @@ execx86(int cycs) } #else wait_cycs(7, 0); - check_interrupts(0); + check_interrupts(); #endif break; case 0x9C: /*PUSHF*/ access(33, 16); - if (is_nec) - tempw = (cpu_state.flags & 0x8fd7) | 0x7000; - else - tempw = (cpu_state.flags & 0x0fd7) | 0xf000; + tempw = (cpu_state.flags & 0x0fd7) | 0xf000; push(&tempw); break; case 0x9D: { /*POPF*/ uint16_t old_flags = cpu_state.flags; access(25, 16); - if (is_nec && cpu_md_write_disable) - cpu_state.flags = pop() | 0x8002; - else - cpu_state.flags = pop() | 0x0002; + cpu_state.flags = pop() | 0x0002; wait_cycs(1, 0); if ((old_flags ^ cpu_state.flags) & T_FLAG) noint = 1; - sync_to_i8080(); break; } case 0x9E: /*SAHF*/ wait_cycs(1, 0); @@ -3306,15 +2838,10 @@ execx86(int cycs) access(62, 8); set_ip(new_ip); access(45, 8); - if (is_nec && cpu_md_write_disable) - cpu_state.flags = pop() | 0x8002; - else - cpu_state.flags = pop() | 0x0002; + cpu_state.flags = pop() | 0x0002; wait_cycs(5, 0); noint = 2; nmi_enable = 1; - if (is_nec && !(cpu_state.flags & MD_FLAG)) - sync_to_i8080(); break; case 0xD0: @@ -3335,7 +2862,7 @@ execx86(int cycs) cpu_src = CL; wait_cycs((cpu_mod != 3) ? 9 : 6, 0); } - if (is186 && !is_nec) + if (is186) cpu_src &= 0x1F; while (cpu_src != 0) { cpu_dest = cpu_data; @@ -3414,15 +2941,7 @@ execx86(int cycs) case 0xD4: /*AAM*/ wait_cycs(1, 0); -#ifdef NO_VARIANT_ON_NEC - if (is_nec) { - (void) pfq_fetchb(); - cpu_src = 10; - } else - cpu_src = pfq_fetchb(); -#else cpu_src = pfq_fetchb(); -#endif if (x86_div(AL, 0)) { cpu_data = AL; set_pzs(8); @@ -3430,11 +2949,7 @@ execx86(int cycs) break; case 0xD5: /*AAD*/ wait_cycs(1, 0); - if (is_nec) { - (void) pfq_fetchb(); - mul(10, AH); - } else - mul(pfq_fetchb(), AH); + mul(pfq_fetchb(), AH); cpu_dest = AL; cpu_src = cpu_data; add(8); @@ -3443,13 +2958,10 @@ execx86(int cycs) set_pzs(8); break; case 0xD6: /*SALC*/ - if (!is_nec) { - wait_cycs(1, 0); - AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00; - wait_cycs(1, 0); - break; - } - fallthrough; + wait_cycs(1, 0); + AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00; + wait_cycs(1, 0); + break; case 0xD7: /*XLATB*/ cpu_state.eaaddr = (BX + AL) & 0xffff; access(4, 8); @@ -3651,9 +3163,9 @@ execx86(int cycs) pfq_clear(); } wait_cycs(1, 0); - if (irq_pending(is_nec)) { + if (irq_pending()) { wait_cycs(cycles & 1, 0); - check_interrupts(is_nec); + check_interrupts(); } else { repeating = 1; completed = 0; @@ -3699,7 +3211,6 @@ execx86(int cycs) break; case 0x20: /* MUL */ case 0x28: /* IMUL */ - old_flags = cpu_state.flags; wait_cycs(1, 0); mul(get_accum(bits), cpu_data); if (opcode & 1) { @@ -3711,17 +3222,12 @@ execx86(int cycs) AL = (uint8_t) cpu_data; AH = (uint8_t) cpu_dest; set_co_mul(bits, AH != ((AL & 0x80) == 0 || (rmdat & 0x38) == 0x20 ? 0 : 0xff)); - if (!is_nec) - cpu_data = AH; + cpu_data = AH; } set_sf(bits); set_pf(); if (cpu_mod != 3) wait_cycs(1, 0); - /* NOTE: When implementing the V20, care should be taken to not change - the zero flag. */ - if (is_nec) - cpu_state.flags = (cpu_state.flags & ~Z_FLAG) | (old_flags & Z_FLAG); break; case 0x30: /* DIV */ case 0x38: /* IDIV */ @@ -3843,7 +3349,7 @@ execx86(int cycs) break; } } -exec_completed: + if (completed) { repeating = 0; ovr_seg = NULL; @@ -3852,7 +3358,7 @@ execx86(int cycs) if (in_lock) clear_lock = 1; clock_end(); - check_interrupts(0); + check_interrupts(); if (noint) noint = 0; diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index dc7f5ac110..7eadb94faa 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -20,6 +20,8 @@ add_library(cpu OBJECT cpu_table.c fpu.c x86.c 808x.c + vx0.c + vx0_biu.c 386.c 386_common.c 386_dynarec.c diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 6e675acc89..e0868861dc 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1865,6 +1865,8 @@ cpu_set(void) cpu_exec = exec386_2386; } else if (cpu_s->cpu_type >= CPU_286) cpu_exec = exec386_2386; + else if (is_nec) + cpu_exec = execvx0; else cpu_exec = execx86; mmx_init(); diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 865e76ffb2..8e74bc78ae 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -718,6 +718,7 @@ extern void codegen_reset(void); extern void cpu_set_edx(void); extern int divl(uint32_t val); extern void execx86(int32_t cycs); +extern void execvx0(int32_t cycs); extern void enter_smm(int in_hlt); extern void enter_smm_check(int in_hlt); extern void leave_smm(void); @@ -809,6 +810,8 @@ extern void SF_FPU_reset(void); extern void reset_808x(int hard); extern void interrupt_808x(uint16_t addr); +extern void reset_vx0(int hard); + extern void cpu_register_fast_off_handler(void *timer); extern void cpu_fast_off_advance(void); extern void cpu_fast_off_period_set(uint16_t vla, double period); diff --git a/src/cpu/vx0.c b/src/cpu/vx0.c new file mode 100644 index 0000000000..bd1a8da201 --- /dev/null +++ b/src/cpu/vx0.c @@ -0,0 +1,4783 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 808x CPU emulation, mostly ported from reenigne's XTCE, which + * is cycle-accurate. + * + * Authors: Andrew Jenner, + * Miran Grca, + * + * Copyright 2015-2020 Andrew Jenner. + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include + +#include "i8080.h" + +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include "x86.h" +#include <86box/machine.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/ppi.h> +#include <86box/timer.h> +#include <86box/gdbstub.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#include "vx0_biu.h" + +#define do_cycle() wait(1) +#define do_cycle_no_modrm() if (!nx) \ + do_cycle() +#define do_cycle_i() do_cycle() +#define do_cycles(c) wait(c) +#define do_cycles_i(c) do_cycles(c) +#define do_cycle_nx() nx = 1 +#define do_cycle_nx_i() nx = 1 +#define do_cycles_nx(c) nx = 1; \ + if (c > 1) \ + do_cycles(c - 1) +#define do_cycles_nx_i(c) nx = 1; \ + if (c > 1) \ + do_cycles(c - 1) +#define addr_mode_match() cpu_mod == 3 +#define math_op(o) cpu_alu_op = o; \ + alu_op(bits) + +/* Various things needed for 8087. */ +#define OP_TABLE(name) ops_##name + +#define CPU_BLOCK_END() +#define SEG_CHECK_READ(seg) +#define SEG_CHECK_WRITE(seg) +#define CHECK_READ(a, b, c) +#define CHECK_WRITE(a, b, c) +#define UN_USED(x) (void) (x) +#define fetch_ea_16(val) +#define fetch_ea_32(val) +#define PREFETCH_RUN(a, b, c, d, e, f, g, h) + +#define CYCLES(val) \ + { \ + do_cycles(val); \ + } + +#define CLOCK_CYCLES_ALWAYS(val) \ + { \ + do_cycles(val); \ + } + +#define CLOCK_CYCLES_FPU(val) \ + { \ + do_cycles(val); \ + } + +# define CLOCK_CYCLES(val) \ + { \ + if (fpu_cycles > 0) { \ + fpu_cycles -= (val); \ + if (fpu_cycles < 0) { \ + do_cycles(val); \ + } \ + } else { \ + do_cycles(val); \ + } \ + } + +#define CONCURRENCY_CYCLES(c) fpu_cycles = (c) + +#define OP_MRM 1 +#define OP_EA 2 +#define OP_MEA (OP_MRM | OP_EA) +#define OP_GRP 4 +#define OP_DELAY 8 +#define OP_PRE 16 + +#define readmemb readmemb_vx0 +#define readmemw readmemw_vx0 +#define readmem readmem_vx0 +#define readmeml readmeml_vx0 +#define readmemq readmemq_vx0 +#define writememb writememb_vx0 +#define writememw writememw_vx0 +#define writemem writemem_vx0 +#define writememl writememl_vx0 +#define writememq writememq_vx0 + +typedef int (*OpFn)(uint32_t fetchdat); + +static void farret(int far); + +const uint8_t opf[256] = { OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, 0, /* 00 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, 0, /* 08 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, 0, /* 10 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, 0, /* 18 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 20 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 28 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 30 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 38 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 40 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 48 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 50 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 58 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 60 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 68 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 78 */ + OP_GRP, OP_GRP, OP_GRP, OP_GRP, OP_MEA, OP_MEA, OP_MEA, OP_MEA, /* 80 */ + OP_MRM, OP_MRM, OP_MEA, OP_MEA, OP_MRM, OP_MRM, OP_MEA, OP_MRM, /* 88 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 90 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 98 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* A0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* A8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* B0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* B8 */ + 0, 0, 0, 0, OP_MEA, OP_MEA, OP_MRM, OP_MRM, /* C0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* C8 */ + OP_GRP, OP_GRP, OP_GRP, OP_GRP, 0, 0, 0, 0, /* D0 */ + OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, /* D8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* E0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* E8 */ + OP_PRE, OP_PRE, OP_PRE, OP_PRE, 0, 0, OP_GRP, OP_GRP, /* F0 */ + 0, 0, 0, 0, 0, 0, OP_GRP, OP_GRP }; /* F8 */ + +const uint8_t opf_nec[256] = { OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, 0, /* 00 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, OP_PRE, /* 08 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, 0, /* 10 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, 0, 0, /* 18 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 20 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 28 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 30 */ + OP_MEA, OP_MEA, OP_MEA, OP_MEA, 0, 0, OP_PRE, 0, /* 38 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 40 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 48 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 50 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 58 */ + 0, 0, OP_MRM, OP_MRM, OP_PRE, OP_PRE, OP_MRM, OP_MRM, /* 60 */ + 0, OP_MRM, 0, OP_MEA, 0, 0, 0, 0, /* 68 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 78 */ + OP_GRP, OP_GRP, OP_GRP, OP_GRP, OP_MEA, OP_MEA, OP_MEA, OP_MEA, /* 80 */ + OP_MRM, OP_MRM, OP_MEA, OP_MEA, OP_MRM, OP_MRM, OP_MEA, OP_MRM, /* 88 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 90 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 98 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* A0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* A8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* B0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* B8 */ + OP_GRP, OP_GRP, 0, 0, OP_MEA, OP_MEA, OP_MRM, OP_MRM, /* C0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* C8 */ + OP_GRP, OP_GRP, OP_GRP, OP_GRP, 0, 0, 0, 0, /* D0 */ + OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, /* D8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* E0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* E8 */ + OP_PRE, OP_PRE, OP_PRE, OP_PRE, 0, 0, OP_GRP, OP_GRP, /* F0 */ + 0, 0, 0, 0, 0, 0, OP_GRP, OP_GRP }; /* F8 */ + +const uint8_t opf_0f[256] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 00 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 08 */ + OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, /* 10 */ + OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, OP_MRM, /* 18 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 20 */ + OP_MRM, 0, OP_MRM, 0, 0, 0, 0, 0, /* 28 */ + OP_MRM, 0, OP_MRM, 0, 0, 0, 0, 0, /* 30 */ + OP_MRM, 0, OP_MRM, 0, 0, 0, 0, 0, /* 38 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 40 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 48 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 50 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 58 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 60 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 68 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 70 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 78 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 80 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 88 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 90 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 98 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* A0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* A8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* B0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* B8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* C0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* C8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* D0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* D8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* E0 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* E8 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* F0 */ + 0, 0, 0, 0, 0, 0, 0, 0 }; /* F8 */ + +uint8_t use_custom_nmi_vector = 0; + +uint32_t custom_nmi_vector = 0x00000000; + +/* Is the CPU 8088 or 8086. */ +int is8086 = 0; +int nx = 0; + +static uint32_t cpu_src = 0; +static uint32_t cpu_dest = 0; + +static uint32_t cpu_data = 0; + +static int oldc; +static int cpu_alu_op; +static int completed = 1; +static int in_rep = 0; +static int repeating = 0; +static int rep_c_flag = 0; +static int clear_lock = 0; +static int noint = 0; +static int tempc_fpu = 0; +static int started = 0; +static int group_delay = 0; +static int modrm_loaded = 0; +static int in_0f = 0; +static int in_hlt = 0; +static int retem = 0; +static int halted = 0; + +static uint32_t * ovr_seg = NULL; + +/* Pointer tables needed for segment overrides. */ +static uint32_t * opseg[4]; + +static x86seg * _opseg[4]; + +enum { + MODRM_ADDR_BX_SI = 0x00, + MODRM_ADDR_BX_DI, + MODRM_ADDR_BP_SI, + MODRM_ADDR_BP_DI, + MODRM_ADDR_SI, + MODRM_ADDR_DI, + MODRM_ADDR_DISP16, + MODRM_ADDR_BX, + + MODRM_ADDR_BX_SI_DISP8 = 0x40, + MODRM_ADDR_BX_DI_DISP8, + MODRM_ADDR_BP_SI_DISP8, + MODRM_ADDR_BP_DI_DISP8, + MODRM_ADDR_SI_DISP8, + MODRM_ADDR_DI_DISP8, + MODRM_ADDR_BP_DISP8, + MODRM_ADDR_BX_DISP8, + + MODRM_ADDR_BX_SI_DISP16 = 0x80, + MODRM_ADDR_BX_DI_DISP16, + MODRM_ADDR_BP_SI_DISP16, + MODRM_ADDR_BP_DI_DISP16, + MODRM_ADDR_SI_DISP16, + MODRM_ADDR_DI_DISP16, + MODRM_ADDR_BP_DISP16, + MODRM_ADDR_BX_DISP16 +}; + +static uint8_t modrm_cycs_pre[256] = { [MODRM_ADDR_BX_SI] = 4, + [MODRM_ADDR_BX_DI] = 5, + [MODRM_ADDR_BP_SI] = 5, + [MODRM_ADDR_BP_DI] = 4, + [MODRM_ADDR_SI] = 2, + [MODRM_ADDR_DI] = 2, + [MODRM_ADDR_DISP16] = 0, + [MODRM_ADDR_BX] = 2, + [0x08 ... 0x3f] = 0, + [MODRM_ADDR_BX_SI_DISP8] = 4, + [MODRM_ADDR_BX_DI_DISP8] = 5, + [MODRM_ADDR_BP_SI_DISP8] = 5, + [MODRM_ADDR_BP_DI_DISP8] = 4, + [MODRM_ADDR_SI_DISP8] = 2, + [MODRM_ADDR_DI_DISP8] = 2, + [MODRM_ADDR_BP_DISP8] = 2, + [MODRM_ADDR_BX_DISP8] = 2, + [0x48 ... 0x7f] = 0, + [MODRM_ADDR_BX_SI_DISP16] = 4, + [MODRM_ADDR_BX_DI_DISP16] = 5, + [MODRM_ADDR_BP_SI_DISP16] = 5, + [MODRM_ADDR_BP_DI_DISP16] = 4, + [MODRM_ADDR_SI_DISP16] = 2, + [MODRM_ADDR_DI_DISP16] = 2, + [MODRM_ADDR_BP_DISP16] = 2, + [MODRM_ADDR_BX_DISP16] = 2, + [0x88 ... 0xff] = 0 }; + +static uint8_t modrm_cycs_post[256] = { [MODRM_ADDR_BX_SI] = 0, + [MODRM_ADDR_BX_DI] = 0, + [MODRM_ADDR_BP_SI] = 0, + [MODRM_ADDR_BP_DI] = 0, + [MODRM_ADDR_SI] = 0, + [MODRM_ADDR_DI] = 0, + [MODRM_ADDR_DISP16] = 1, + [MODRM_ADDR_BX] = 0, + [0x08 ... 0x3f] = 0, + [MODRM_ADDR_BX_SI_DISP8] = 3, + [MODRM_ADDR_BX_DI_DISP8] = 3, + [MODRM_ADDR_BP_SI_DISP8] = 3, + [MODRM_ADDR_BP_DI_DISP8] = 3, + [MODRM_ADDR_SI_DISP8] = 3, + [MODRM_ADDR_DI_DISP8] = 3, + [MODRM_ADDR_BP_DISP8] = 3, + [MODRM_ADDR_BX_DISP8] = 3, + [0x48 ... 0x7f] = 0, + [MODRM_ADDR_BX_SI_DISP16] = 2, + [MODRM_ADDR_BX_DI_DISP16] = 2, + [MODRM_ADDR_BP_SI_DISP16] = 2, + [MODRM_ADDR_BP_DI_DISP16] = 2, + [MODRM_ADDR_SI_DISP16] = 2, + [MODRM_ADDR_DI_DISP16] = 2, + [MODRM_ADDR_BP_DISP16] = 2, + [MODRM_ADDR_BX_DISP16] = 2, + [0x88 ... 0xff] = 0 }; + +#ifdef ENABLE_808X_LOG +#if 0 +void dumpregs(int); +#endif +int x808x_do_log = ENABLE_808X_LOG; + +static void +x808x_log(const char *fmt, ...) +{ + va_list ap; + + if (x808x_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define x808x_log(fmt, ...) +#endif + +static i8080 emulated_processor; +static bool cpu_md_write_disable = 1; + +static void +set_if(int cond) +{ + cpu_state.flags = (cpu_state.flags & ~I_FLAG) | (cond ? I_FLAG : 0); +} + +void +sync_from_i8080(void) +{ + AL = emulated_processor.a; + BH = emulated_processor.h; + BL = emulated_processor.l; + CH = emulated_processor.b; + CL = emulated_processor.c; + DH = emulated_processor.d; + DL = emulated_processor.e; + BP = emulated_processor.sp; + + cpu_state.pc = emulated_processor.pc; + cpu_state.flags &= 0xFF00; + cpu_state.flags |= emulated_processor.sf << 7; + cpu_state.flags |= emulated_processor.zf << 6; + cpu_state.flags |= emulated_processor.hf << 4; + cpu_state.flags |= emulated_processor.pf << 2; + cpu_state.flags |= 1 << 1; + cpu_state.flags |= emulated_processor.cf << 0; + set_if(emulated_processor.iff); +} + +void +sync_to_i8080(void) +{ + if (!is_nec) + return; + emulated_processor.a = AL; + emulated_processor.h = BH; + emulated_processor.l = BL; + emulated_processor.b = CH; + emulated_processor.c = CL; + emulated_processor.d = DH; + emulated_processor.e = DL; + emulated_processor.sp = BP; + emulated_processor.pc = cpu_state.pc; + emulated_processor.iff = !!(cpu_state.flags & I_FLAG); + + emulated_processor.sf = (cpu_state.flags >> 7) & 1; + emulated_processor.zf = (cpu_state.flags >> 6) & 1; + emulated_processor.hf = (cpu_state.flags >> 4) & 1; + emulated_processor.pf = (cpu_state.flags >> 2) & 1; + emulated_processor.cf = (cpu_state.flags >> 0) & 1; + + emulated_processor.interrupt_delay = noint; +} + +uint16_t +get_last_addr(void) +{ + return last_addr; +} + +static void +set_ip(uint16_t new_ip) +{ + cpu_state.pc = new_ip; +} + +static void +startx86(void) +{ + /* Reset takes 6 cycles before first fetch. */ + do_cycle(); + biu_suspend_fetch(); + do_cycles_i(2); + biu_queue_flush(); + do_cycles_i(3); +} + +static void +load_cs(uint16_t seg) +{ + cpu_state.seg_cs.base = seg << 4; + cpu_state.seg_cs.seg = seg & 0xffff; +} + +static void +load_seg(uint16_t seg, x86seg *s) +{ + s->base = seg << 4; + s->seg = seg & 0xffff; +} + +static uint8_t +fetch_i8080_opcode(UNUSED(void* priv), uint16_t addr) +{ + return readmemb(cs, addr); +} + +static uint8_t +fetch_i8080_data(UNUSED(void* priv), uint16_t addr) +{ + return readmemb(ds, addr); +} + +static void +put_i8080_data(UNUSED(void* priv), uint16_t addr, uint8_t val) +{ + writememb(ds, addr, val); +} + +static +uint8_t i8080_port_in(UNUSED(void* priv), uint8_t port) +{ + cpu_data = port; + cpu_state.eaaddr = cpu_data; + cpu_io_vx0(8, 0, cpu_state.eaaddr); + return AL; +} + +static +void i8080_port_out(UNUSED(void* priv), uint8_t port, uint8_t val) +{ + cpu_data = DX; + AL = val; + do_cycle_i(); + + cpu_state.eaaddr = cpu_data; + cpu_data = AL; + cpu_io_vx0(8, 1, port); +} + +void +reset_vx0(int hard) +{ + halted = 0; + in_hlt = 0; + in_0f = 0; + in_rep = 0; + in_lock = 0; + completed = 1; + repeating = 0; + clear_lock = 0; + ovr_seg = NULL; + + if (hard) { + opseg[0] = &es; + opseg[1] = &cs; + opseg[2] = &ss; + opseg[3] = &ds; + _opseg[0] = &cpu_state.seg_es; + _opseg[1] = &cpu_state.seg_cs; + _opseg[2] = &cpu_state.seg_ss; + _opseg[3] = &cpu_state.seg_ds; + } + + load_cs(0xFFFF); + cpu_state.pc = 0; + + if (is_nec) + cpu_state.flags |= MD_FLAG; + rammask = 0xfffff; + + cpu_alu_op = 0; + + nx = 0; + + use_custom_nmi_vector = 0x00; + custom_nmi_vector = 0x00000000; + + biu_reset(); + + started = 1; + modrm_loaded = 0; + + cpu_md_write_disable = 1; + i8080_init(&emulated_processor); + emulated_processor.write_byte = put_i8080_data; + emulated_processor.read_byte = fetch_i8080_data; + emulated_processor.read_byte_seg = fetch_i8080_opcode; + emulated_processor.port_in = i8080_port_in; + emulated_processor.port_out = i8080_port_out; +} + +static uint16_t +get_accum(int bits) +{ + return (bits == 16) ? AX : AL; +} + +static void +set_accum(int bits, uint16_t val) +{ + if (bits == 16) + AX = val; + else + AL = val; +} + +static uint16_t +sign_extend(uint8_t data) +{ + return data + (data < 0x80 ? 0 : 0xff00); +} + +#undef getr8 +#define getr8(r) ((r & 4) ? cpu_state.regs[r & 3].b.h : cpu_state.regs[r & 3].b.l) + +#undef setr8 +#define setr8(r, v) \ + if (r & 4) \ + cpu_state.regs[r & 3].b.h = v; \ + else \ + cpu_state.regs[r & 3].b.l = v; + +/* Reads a byte from the effective address. */ +static uint8_t +geteab(void) +{ + uint8_t ret; + + if (cpu_mod == 3) + ret = (getr8(cpu_rm)); + else + ret = readmemb(easeg, cpu_state.eaaddr); + + return ret; +} + +/* Reads a word from the effective address. */ +static uint16_t +geteaw(void) +{ + uint16_t ret; + + if (cpu_mod == 3) + ret = cpu_state.regs[cpu_rm].w; + else + ret = readmemw(easeg, cpu_state.eaaddr); + + return ret; +} + +/* Neede for 8087 - memory only. */ +static uint32_t +geteal(void) +{ + uint32_t ret; + + if (cpu_mod == 3) { + fatal("808x register geteal()\n"); + ret = 0xffffffff; + } else + ret = readmeml(easeg, cpu_state.eaaddr); + + return ret; +} + +/* Neede for 8087 - memory only. */ +static uint64_t +geteaq(void) +{ + uint32_t ret; + + if (cpu_mod == 3) { + fatal("808x register geteaq()\n"); + ret = 0xffffffff; + } else + ret = readmemq(easeg, cpu_state.eaaddr); + + return ret; +} + +static void +read_ea(int memory_only, int bits) +{ + if (cpu_mod != 3) { + if (bits == 16) + cpu_data = readmemw(easeg, cpu_state.eaaddr); + else + cpu_data = readmemb(easeg, cpu_state.eaaddr); + return; + } + if (!memory_only) { + if (bits == 8) { + cpu_data = getr8(cpu_rm); + } else + cpu_data = cpu_state.regs[cpu_rm].w; + } +} + +static void +read_ea_8to16(void) +{ + cpu_data = cpu_state.regs[cpu_rm & 3].w; +} + +static void +read_ea2(int bits) +{ + cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; + if (bits == 16) + cpu_data = readmemw(easeg, cpu_state.eaaddr); + else + cpu_data = readmemb(easeg, cpu_state.eaaddr); +} + +/* Writes a byte to the effective address. */ +static void +seteab(uint8_t val) +{ + if (cpu_mod == 3) { + setr8(cpu_rm, val); + } else { + do_cycle(); + writememb(easeg, cpu_state.eaaddr, val); + } +} + +/* Writes a word to the effective address. */ +static void +seteaw(uint16_t val) +{ + if (cpu_mod == 3) + cpu_state.regs[cpu_rm].w = val; + else { + do_cycle(); + writememw(easeg, cpu_state.eaaddr, val); + } +} + +static void +seteal(uint32_t val) +{ + if (cpu_mod == 3) { + fatal("808x register seteal()\n"); + return; + } else + writememl(easeg, cpu_state.eaaddr, val); +} + +static void +seteaq(uint64_t val) +{ + if (cpu_mod == 3) { + fatal("808x register seteaq()\n"); + return; + } else + writememq(easeg, cpu_state.eaaddr, val); +} + +/* Leave out the 686 stuff as it's not needed and + complicates compiling. */ +#define FPU_8087 +#define FPU_NEC +#define tempc tempc_fpu +#include "x87_sf.h" +#include "x87.h" +#include "x87_ops.h" +#undef tempc +#undef FPU_8087 + +static void +set_cf(int cond) +{ + cpu_state.flags = (cpu_state.flags & ~C_FLAG) | (cond ? C_FLAG : 0); +} + +static void +set_df(int cond) +{ + cpu_state.flags = (cpu_state.flags & ~D_FLAG) | (cond ? D_FLAG : 0); +} + +static void +set_of(int of) +{ + cpu_state.flags = (cpu_state.flags & ~0x800) | (of ? 0x800 : 0); +} + +static int +top_bit(uint16_t w, int bits) +{ + return (w & (1 << (bits - 1))); +} + +static void +set_of_add(int bits) +{ + set_of(top_bit((cpu_data ^ cpu_src) & (cpu_data ^ cpu_dest), bits)); +} + +static void +set_of_sub(int bits) +{ + set_of(top_bit((cpu_dest ^ cpu_src) & (cpu_data ^ cpu_dest), bits)); +} + +static void +set_af(int af) +{ + cpu_state.flags = (cpu_state.flags & ~0x10) | (af ? 0x10 : 0); +} + +static void +do_af(void) +{ + set_af(((cpu_data ^ cpu_src ^ cpu_dest) & 0x10) != 0); +} + +static void +set_sf(int bits) +{ + cpu_state.flags = (cpu_state.flags & ~0x80) | (top_bit(cpu_data, bits) ? 0x80 : 0); +} + +static void +set_pf(void) +{ + cpu_state.flags = (cpu_state.flags & ~4) | (!__builtin_parity(cpu_data & 0xFF) << 2); +} + +static void +set_of_rotate(int bits) +{ + set_of(top_bit(cpu_data ^ cpu_dest, bits)); +} + +static void +set_zf_ex(int zf) +{ + cpu_state.flags = (cpu_state.flags & ~0x40) | (zf ? 0x40 : 0); +} + +static void +set_zf(int bits) +{ + int size_mask = (1 << bits) - 1; + + set_zf_ex((cpu_data & size_mask) == 0); +} + +static void +set_pzs(int bits) +{ + set_pf(); + set_zf(bits); + set_sf(bits); +} + +static void +set_apzs(int bits) +{ + set_pzs(bits); + do_af(); +} + +static void +add(int bits) +{ + int size_mask = (1 << bits) - 1; + + cpu_data = cpu_dest + cpu_src; + set_apzs(bits); + set_of_add(bits); + + /* Anything - FF with carry on is basically anything + 0x100: value stays + unchanged but carry goes on. */ + if ((cpu_alu_op == 2) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + cpu_state.flags |= C_FLAG; + else + set_cf((cpu_src & size_mask) > (cpu_data & size_mask)); +} + +static void +sub(int bits) +{ + int size_mask = (1 << bits) - 1; + + cpu_data = cpu_dest - cpu_src; + set_apzs(bits); + set_of_sub(bits); + + /* Anything - FF with carry on is basically anything - 0x100: value stays + unchanged but carry goes on. */ + if ((cpu_alu_op == 3) && !(cpu_src & size_mask) && (cpu_state.flags & C_FLAG)) + cpu_state.flags |= C_FLAG; + else + set_cf((cpu_src & size_mask) > (cpu_dest & size_mask)); +} + +static void +bitwise(int bits, uint16_t data) +{ + cpu_data = data; + cpu_state.flags &= ~(C_FLAG | A_FLAG | V_FLAG); + set_pzs(bits); +} + +static void +test(int bits, uint16_t dest, uint16_t src) +{ + cpu_dest = dest; + cpu_src = src; + bitwise(bits, (cpu_dest & cpu_src)); +} + +static void +alu_op(int bits) +{ + switch (cpu_alu_op) { + case 1: + bitwise(bits, (cpu_dest | cpu_src)); + break; + case 2: + if (cpu_state.flags & C_FLAG) + cpu_src++; + fallthrough; + case 0: + add(bits); + break; + case 3: + if (cpu_state.flags & C_FLAG) + cpu_src++; + fallthrough; + case 5: + case 7: + sub(bits); + break; + case 4: + test(bits, cpu_dest, cpu_src); + break; + case 6: + bitwise(bits, (cpu_dest ^ cpu_src)); + break; + + default: + break; + } +} + +static void +mul(uint16_t a, uint16_t b) +{ + int negate = 0; + int bit_count = 8; + int carry; + uint16_t high_bit = 0x80; + uint16_t size_mask; + uint16_t c; + uint16_t r; + + size_mask = (1 << bit_count) - 1; + + if (opcode != 0xd5) { + if (opcode & 1) { + bit_count = 16; + high_bit = 0x8000; + } else + do_cycles(8); + + size_mask = (1 << bit_count) - 1; + + if ((rmdat & 0x38) == 0x28) { + if (!top_bit(a, bit_count)) { + if (top_bit(b, bit_count)) { + do_cycle(); + if ((b & size_mask) != ((opcode & 1) ? 0x8000 : 0x80)) + do_cycle(); + b = ~b + 1; + negate = 1; + } + } else { + do_cycle(); + a = ~a + 1; + negate = 1; + if (top_bit(b, bit_count)) { + b = ~b + 1; + negate = 0; + } else + do_cycles(4); + } + do_cycles(10); + } + do_cycles(3); + } + + c = 0; + a &= size_mask; + carry = (a & 1) != 0; + a >>= 1; + for (int i = 0; i < bit_count; ++i) { + do_cycles(7); + if (carry) { + cpu_src = c; + cpu_dest = b; + add(bit_count); + c = cpu_data & size_mask; + do_cycles(1); + carry = !!(cpu_state.flags & C_FLAG); + } + r = (c >> 1) + (carry ? high_bit : 0); + carry = (c & 1) != 0; + c = r; + r = (a >> 1) + (carry ? high_bit : 0); + carry = (a & 1) != 0; + a = r; + } + if (negate) { + c = ~c; + a = (~a + 1) & size_mask; + if (a == 0) + ++c; + do_cycles(9); + } + cpu_data = a; + cpu_dest = c; + + set_sf(bit_count); + set_pf(); + set_af(0); +} + +static void +set_co_mul(UNUSED(int bits), int carry) +{ + set_cf(carry); + set_of(carry); + set_zf_ex(!carry); + if (!carry) + do_cycle(); +} + +/* Pushes a word to the stack. */ +static void +push(uint16_t *val) +{ + if ((is186 && !is_nec) && (SP == 1)) { + writememw(ss - 1, 0, *val); + SP = cpu_state.eaaddr = 0xFFFF; + return; + } + SP -= 2; + cpu_state.eaaddr = (SP & 0xffff); + writememw(ss, cpu_state.eaaddr, *val); +} + +/* Pops a word from the stack. */ +static uint16_t +pop(void) +{ + cpu_state.eaaddr = (SP & 0xffff); + SP += 2; + return readmemw(ss, cpu_state.eaaddr); +} + +static void +nearcall(uint16_t new_ip) +{ + uint16_t ret_ip = cpu_state.pc & 0xffff; + + do_cycle_i(); + set_ip(new_ip); + biu_queue_flush(); + do_cycles_i(3); + push(&ret_ip); +} + +static void +farcall2(uint16_t new_cs, uint16_t new_ip) +{ + do_cycles_i(3); + push(&CS); + load_cs(new_cs); + do_cycles_i(2); + nearcall(new_ip); +} + +/* The INTR microcode routine. */ +static void +intr_routine(uint16_t intr, int skip_first) +{ + uint16_t vector = intr * 4; + uint16_t tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); + uint16_t new_cs; + uint16_t new_ip; + + if (!(cpu_state.flags & MD_FLAG) && is_nec) { + sync_from_i8080(); + x808x_log("CALLN/INT#/NMI#\n"); + } + + if (!skip_first) + do_cycle_i(); + do_cycles_i(2); + + cpu_state.eaaddr = vector & 0xffff; + new_ip = readmemw(0, cpu_state.eaaddr); + do_cycle_i(); + cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; + new_cs = readmemw(0, cpu_state.eaaddr); + + biu_suspend_fetch(); + do_cycles_i(2); + push(&tempf); + cpu_state.flags &= ~(I_FLAG | T_FLAG); + if (is_nec) + cpu_state.flags |= MD_FLAG; + do_cycle_i(); + + farcall2(new_cs, new_ip); +} + +/* Was div(), renamed to avoid conflicts with stdlib div(). */ +static int +x86_div(uint16_t l, uint16_t h) +{ + int bit_count = 8; + int negative = 0; + int dividend_negative = 0; + int size_mask; + int carry; + uint16_t r; + + if (opcode & 1) { + l = AX; + h = DX; + bit_count = 16; + } + + size_mask = (1 << bit_count) - 1; + + if (opcode != 0xd4) { + if ((rmdat & 0x38) == 0x38) { + if (top_bit(h, bit_count)) { + h = ~h; + l = (~l + 1) & size_mask; + if (l == 0) + ++h; + h &= size_mask; + negative = 1; + dividend_negative = 1; + do_cycles(4); + } + if (top_bit(cpu_src, bit_count)) { + cpu_src = ~cpu_src + 1; + negative = !negative; + } else + do_cycle(); + do_cycles(9); + } + do_cycles(3); + } + do_cycles(8); + cpu_src &= size_mask; + if (h >= cpu_src) { + if (opcode != 0xd4) + do_cycle(); + intr_routine(0, 0); + return 0; + } + if (opcode != 0xd4) + do_cycle(); + do_cycles(2); + carry = 1; + for (int b = 0; b < bit_count; ++b) { + r = (l << 1) + (carry ? 1 : 0); + carry = top_bit(l, bit_count); + l = r; + r = (h << 1) + (carry ? 1 : 0); + carry = top_bit(h, bit_count); + h = r; + do_cycles(8); + if (carry) { + carry = 0; + h -= cpu_src; + if (b == bit_count - 1) + do_cycles(2); + } else { + carry = cpu_src > h; + if (!carry) { + h -= cpu_src; + do_cycle(); + if (b == bit_count - 1) + do_cycles(2); + } + } + } + l = ~((l << 1) + (carry ? 1 : 0)); + if (opcode != 0xd4 && (rmdat & 0x38) == 0x38) { + do_cycles(4); + if (top_bit(l, bit_count)) { + if (cpu_mod == 3) + do_cycle(); + intr_routine(0, 0); + return 0; + } + do_cycles(7); + if (negative) + l = ~l + 1; + if (dividend_negative) + h = ~h + 1; + } + if (opcode == 0xd4) { + AL = h & 0xff; + AH = l & 0xff; + } else { + AH = h & 0xff; + AL = l & 0xff; + if (opcode & 1) { + DX = h; + AX = l; + } + } + return 1; +} + +static uint16_t +string_increment(int bits) +{ + int d = bits >> 3; + if (cpu_state.flags & D_FLAG) + cpu_state.eaaddr -= d; + else + cpu_state.eaaddr += d; + cpu_state.eaaddr &= 0xffff; + return cpu_state.eaaddr; +} + +static void +lods(int bits) +{ + cpu_state.eaaddr = SI; + if (bits == 16) + cpu_data = readmemw((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + else + cpu_data = readmemb((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + SI = string_increment(bits); +} + +static void +lods_di(int bits) +{ + cpu_state.eaaddr = DI; + if (bits == 16) + cpu_data = readmemw(es, cpu_state.eaaddr); + else + cpu_data = readmemb(es, cpu_state.eaaddr); + DI = string_increment(bits); +} + +static void +stos(int bits) +{ + cpu_state.eaaddr = DI; + if (bits == 16) + writememw(es, cpu_state.eaaddr, cpu_data); + else + writememb(es, cpu_state.eaaddr, (uint8_t) (cpu_data & 0xff)); + DI = string_increment(bits); +} + +static uint16_t +get_ea(void) +{ + if (opcode & 1) + return geteaw(); + else + return (uint16_t) geteab(); +} + +static uint16_t +get_reg(uint8_t reg) +{ + if (opcode & 1) + return cpu_state.regs[reg].w; + else + return (uint16_t) getr8(reg); +} + +static void +set_ea(uint16_t val) +{ + if (opcode & 1) + seteaw(val); + else + seteab((uint8_t) (val & 0xff)); +} + +static void +set_reg(uint8_t reg, uint16_t val) +{ + if (opcode & 1) + cpu_state.regs[reg].w = val; + else + setr8(reg, (uint8_t) (val & 0xff)); +} + +static void +cpu_data_opff_rm(void) +{ + if (!(opcode & 1)) { + if (cpu_mod != 3) + cpu_data |= 0xff00; + else + cpu_data = cpu_state.regs[cpu_rm].w; + } +} + +static void +farcall(uint16_t new_cs, uint16_t new_ip, int jump) +{ + if (jump) + do_cycle_i(); + biu_suspend_fetch(); + do_cycles_i(2); + push(&CS); + load_cs(new_cs); + do_cycles_i(2); + nearcall(new_ip); +} + +/* Calls an interrupt. */ +static void +sw_int(uint16_t intr) +{ + uint16_t vector = intr * 4; + uint16_t tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); + uint16_t new_cs; + uint16_t new_ip; + uint16_t old_ip; + + if (!(cpu_state.flags & MD_FLAG) && is_nec) { + sync_from_i8080(); + x808x_log("CALLN/INT#/NMI#\n"); + } + + do_cycles_i(3); + cpu_state.eaaddr = vector & 0xffff; + new_ip = readmemw(0, cpu_state.eaaddr); + do_cycle_i(); + cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; + new_cs = readmemw(0, cpu_state.eaaddr); + + biu_suspend_fetch(); + do_cycles_i(2); + push(&tempf); + cpu_state.flags &= ~(I_FLAG | T_FLAG); + if (is_nec) + cpu_state.flags |= MD_FLAG; + + /* FARCALL2 */ + do_cycles_i(4); + push(&CS); + load_cs(new_cs); + do_cycle_i(); + + /* NEARCALL */ + old_ip = cpu_state.pc & 0xffff; + do_cycles_i(2); + set_ip(new_ip); + biu_queue_flush(); + do_cycles_i(3); + push(&old_ip); +} + +static void +int3(void) +{ + do_cycles_i(4); + intr_routine(3, 0); +} + +/* Ditto, but for breaking into emulation mode. */ +static void +interrupt_brkem(uint16_t addr) +{ + uint16_t tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); + uint16_t new_cs; + uint16_t new_ip; + uint16_t old_ip; + + do_cycles_i(3); + cpu_state.eaaddr = addr << 2; + new_ip = readmemw(0, cpu_state.eaaddr); + do_cycle_i(); + cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; + new_cs = readmemw(0, cpu_state.eaaddr); + + biu_suspend_fetch(); + do_cycles_i(2); + push(&tempf); + cpu_state.flags &= ~(MD_FLAG); + cpu_md_write_disable = 0; + + /* FARCALL2 */ + do_cycles_i(4); + push(&CS); + load_cs(new_cs); + do_cycle_i(); + + /* NEARCALL */ + old_ip = cpu_state.pc & 0xffff; + do_cycles_i(2); + set_ip(new_ip); + biu_queue_flush(); + do_cycles_i(3); + push(&old_ip); + + sync_to_i8080(); + x808x_log("BRKEM mode\n"); +} + +void +retem_i8080(void) +{ + sync_from_i8080(); + + do_cycle_i(); + farret(1); + /* pop_flags() */ + cpu_state.flags = pop(); + do_cycle_i(); + + noint = 1; + nmi_enable = 1; + + emulated_processor.iff = !!(cpu_state.flags & I_FLAG); + + cpu_md_write_disable = 1; + + retem = 1; + + x808x_log("RETEM mode\n"); +} + +void +interrupt_808x(uint16_t addr) +{ + biu_suspend_fetch(); + do_cycles_i(2); + + intr_routine(addr, 0); +} + +static void +custom_nmi(void) +{ + uint16_t tempf = cpu_state.flags & (is_nec ? 0x8fd7 : 0x0fd7); + uint16_t new_cs; + uint16_t new_ip; + + if (!(cpu_state.flags & MD_FLAG) && is_nec) { + sync_from_i8080(); + x808x_log("CALLN/INT#/NMI#\n"); + } + + do_cycle_i(); + do_cycles_i(2); + + cpu_state.eaaddr = 0x0002; + (void) readmemw(0, cpu_state.eaaddr); + new_ip = custom_nmi_vector & 0xffff; + do_cycle_i(); + cpu_state.eaaddr = (cpu_state.eaaddr + 2) & 0xffff; + (void) readmemw(0, cpu_state.eaaddr); + new_cs = custom_nmi_vector >> 16; + + biu_suspend_fetch(); + do_cycles_i(2); + push(&tempf); + cpu_state.flags &= ~(I_FLAG | T_FLAG); + if (is_nec) + cpu_state.flags |= MD_FLAG; + do_cycle_i(); + + farcall2(new_cs, new_ip); +} + +static int +irq_pending(void) +{ + uint8_t temp; + + temp = (nmi && nmi_enable && nmi_mask) || ((cpu_state.flags & T_FLAG) && !noint) || + ((in_hlt || (cpu_state.flags & I_FLAG)) && pic.int_pending && !noint); + + return temp; +} + +static int +bus_pic_ack(void) +{ + int old_in_lock = in_lock; + + in_lock = 1; + bus_request_type = BUS_PIC; + biu_begin_eu(); + biu_wait_for_read_finish(); + in_lock = old_in_lock; + return pic_data; +} + +static void +hw_int(uint16_t vector) +{ + biu_suspend_fetch(); + do_cycles_i(2); + + intr_routine(vector, 0); +} + +static void +int1(void) +{ + do_cycles_i(2); + intr_routine(1, 1); +} + +static void +int2(void) +{ + do_cycles_i(2); + intr_routine(2, 1); +} + +static void +check_interrupts(void) +{ + int temp; + + if (irq_pending()) { + if ((cpu_state.flags & T_FLAG) && !noint) { + int1(); + return; + } + if (nmi && nmi_enable && nmi_mask) { + nmi_enable = 0; + if (use_custom_nmi_vector) { + do_cycles(2); + custom_nmi(); + } else + int2(); + return; + } + if ((in_hlt || (cpu_state.flags & I_FLAG)) && pic.int_pending && !noint) { + repeating = 0; + completed = 1; + ovr_seg = NULL; + do_cycles(4); + /* ACK to PIC */ + biu_begin_eu(); + temp = bus_pic_ack(); + do_cycle(); + /* ACK to PIC */ + temp = bus_pic_ack(); + in_lock = 0; + clear_lock = 0; + /* Here is where temp should be filled, but we cheat. */ + opcode = 0x00; + hw_int(temp); + } + } +} + +/* The FARRET microcode routine. */ +static void +farret(int far) +{ + uint8_t far2 = !!(opcode & 0x08); + + do_cycle_i(); + set_ip(pop()); + biu_suspend_fetch(); + do_cycles_i(2); + + if ((!!far) != far2) + fatal("Far call distance mismatch (%i = %i)\n", !!far, far2); + + if (far) { + do_cycle_i(); + load_cs(pop()); + + biu_queue_flush(); + do_cycles_i(2); + } else { + biu_queue_flush(); + do_cycles_i(2); + } + + do_cycles_i(2); +} + +static void +iret_routine(void) +{ + do_cycle_i(); + farret(1); + /* pop_flags() */ + if (is_nec && cpu_md_write_disable) + cpu_state.flags = pop() | 0x8002; + else + cpu_state.flags = pop() | 0x0002; + do_cycle_i(); + noint = 1; + nmi_enable = 1; +} + +static void +rep_end(void) +{ + repeating = 0; + in_rep = 0; + completed = 1; +} + +static int +rep_start(void) +{ + if (!repeating) { + if (in_rep != 0) { + if (CX == 0) { + do_cycles_i(is_nec ? 1 : 4); + rep_end(); + return 0; + } else + do_cycles_i(is_nec ? 1 : 7); + } + } + + completed = 1; + return 1; +} + +static void +rep_interrupt(void) +{ + biu_suspend_fetch(); + do_cycles_i(4); + biu_queue_flush(); + + if (is_nec && (ovr_seg != NULL)) + set_ip((cpu_state.pc - 3) & 0xffff); + else + set_ip((cpu_state.pc - 2) & 0xffff); + + rep_end(); +} + +static void +sign_extend_al(void) +{ + if ((AL & 0x80) != 0) + AH = 0xff; + else + AH = 0x00; +} + +static void +sign_extend_ax(void) +{ + do_cycles(3); + if ((AX & 0x8000) == 0) + DX = 0x0000; + else { + do_cycle(); + DX = 0xffff; + } +} + +static void +reljmp(uint16_t new_ip, int jump) +{ + if (!is_nec && jump) + do_cycle_i(); + + biu_suspend_fetch(); + if (!is_nec) + do_cycles_i(3); + set_ip(new_ip); + biu_queue_flush(); + do_cycle_i(); +} + +static void +daa(void) +{ + uint16_t old_cf = cpu_state.flags & C_FLAG; + uint16_t old_af = cpu_state.flags & A_FLAG; + uint8_t old_al = AL; + uint8_t al_check; + + cpu_state.flags &= ~C_FLAG; + + al_check = (old_af ? 0x9f : 0x99); + + cpu_state.flags &= ~V_FLAG; + if (old_cf) { + if ((AL >= 0x1a) && (AL <= 0x7f)) + cpu_state.flags |= V_FLAG; + } else if ((AL >= 0x7a) && (AL <= 0x7f)) + cpu_state.flags |= V_FLAG; + + if (((AL & 0x0f) > 9) || (cpu_state.flags & A_FLAG)) { + AL += 6; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; + + if ((old_al > al_check) || old_cf) { + AL += 0x60; + cpu_state.flags |= C_FLAG; + } else + cpu_state.flags &= ~C_FLAG; + + set_pzs(8); +} + +static void +das(void) +{ + uint8_t old_al = AL; + uint16_t old_af = cpu_state.flags & A_FLAG; + uint16_t old_cf = cpu_state.flags & C_FLAG; + uint8_t al_check = (old_af ? 0x9f : 0x99); + + cpu_state.flags &= ~V_FLAG; + + if (!old_af && !old_cf) { + if ((AL >= 0x9a) && (AL <= 0xdf)) + cpu_state.flags |= V_FLAG; + } else if (old_af && !old_cf) { + if (((AL >= 0x80) && (AL <= 0x85)) || ((AL >= 0xa0) && (AL <= 0xe5))) + cpu_state.flags |= V_FLAG; + } else if (!old_af && old_cf) { + if ((AL >= 0x80) && (AL <= 0xdf)) + cpu_state.flags |= V_FLAG; + } else if (old_af && old_cf) { + if ((AL >= 0x80) && (AL <= 0xe5)) + cpu_state.flags |= V_FLAG; + } + + cpu_state.flags &= ~C_FLAG; + if (((AL & 0x0f) > 9) || (cpu_state.flags & A_FLAG)) { + AL -= 6; + cpu_state.flags |= A_FLAG; + } else + cpu_state.flags &= ~A_FLAG; + + if ((old_al > al_check) || old_cf) { + AL -= 0x60; + cpu_state.flags |= C_FLAG; + } else + cpu_state.flags &= ~C_FLAG; + + set_pzs(8); +} + +static void +aaa(void) +{ + uint8_t old_al = AL; + uint8_t new_al; + + if (((AL & 0x0f) > 9) || (cpu_state.flags & A_FLAG)) { + AH += 1; + new_al = AL + 6; + AL = new_al & 0x0f; + cpu_state.flags |= A_FLAG; + cpu_state.flags |= C_FLAG; + } else { + new_al = AL; + AL &= 0x0f; + cpu_state.flags &= ~A_FLAG; + cpu_state.flags &= ~C_FLAG; + do_cycle_i(); + } + + cpu_state.flags &= ~(V_FLAG | Z_FLAG | N_FLAG); + if (new_al == 0x00) + cpu_state.flags |= Z_FLAG; + if ((old_al >= 0x7a) && (old_al <= 0x7f)) + cpu_state.flags |= V_FLAG; + if ((old_al >= 0x7a) && (old_al <= 0xf9)) + cpu_state.flags |= N_FLAG; + + cpu_data = new_al; + set_pf(); +} + +static void +aas(void) +{ + uint8_t old_al = AL; + uint16_t old_af = cpu_state.flags & A_FLAG; + uint8_t new_al; + + do_cycles_i(6); + + if (((AL & 0x0f) > 9) || old_af) { + new_al = AL - 6; + AH++; + AL = new_al & 0x0f; + cpu_state.flags |= (A_FLAG | C_FLAG); + } else { + new_al = AL; + AL &= 0x0f; + cpu_state.flags &= ~(C_FLAG | A_FLAG); + do_cycle_i(); + } + + cpu_state.flags &= ~(V_FLAG | Z_FLAG | N_FLAG); + if (new_al == 0x00) + cpu_state.flags |= Z_FLAG; + if (old_af && (old_al >= 0x80) && (old_al <= 0x85)) + cpu_state.flags |= V_FLAG; + if (!old_af && (old_al >= 0x80)) + cpu_state.flags |= N_FLAG; + if (old_af && ((old_al <= 0x05) || (old_al >= 0x86))) + cpu_state.flags |= N_FLAG; + + cpu_data = new_al; + set_pf(); +} + +static void +finalize(void) +{ + in_0f = 0; + repeating = 0; + ovr_seg = NULL; + in_rep = 0; + rep_c_flag = 0; + if (in_lock) + clear_lock = 1; + cpu_alu_op = 0; + + if (pfq_pos == 0) { + do { + if (nx) + nx = 0; + do_cycle(); + } while (pfq_pos == 0); + biu_preload_byte = biu_pfq_read(); + biu_queue_preload = 1; + do_cycle(); + } else { + biu_queue_preload = 1; + biu_preload_byte = biu_pfq_read(); + + biu_resume_on_queue_read(); + + do_cycle(); + } + + if (irq_pending()) + cpu_state.pc--; +} + +/* Fetches the effective address from the prefetch queue according to MOD and R/M. */ +static void +do_mod_rm(void) +{ + rmdat = biu_pfq_fetchb(); + cpu_reg = (rmdat >> 3) & 7; + cpu_mod = (rmdat >> 6) & 3; + cpu_rm = rmdat & 7; + + if (cpu_mod != 3) { + do_cycle(); + if (is_nec) + do_cycle(); + else if (modrm_cycs_pre[rmdat & 0xc7]) + do_cycles(modrm_cycs_pre[rmdat & 0xc7]); + + if ((rmdat & 0xc7) == 0x06) { + cpu_state.eaaddr = biu_pfq_fetchw(); + easeg = ovr_seg ? *ovr_seg : ds; + } else { + cpu_state.eaaddr = (*mod1add[0][cpu_rm]) + (*mod1add[1][cpu_rm]); + easeg = ovr_seg ? *ovr_seg : *mod1seg[cpu_rm]; + switch (rmdat & 0xc0) { + default: + break; + case 0x40: + cpu_state.eaaddr += sign_extend(biu_pfq_fetchb()); + break; + case 0x80: + cpu_state.eaaddr += biu_pfq_fetchw(); + break; + } + cpu_state.eaaddr &= 0xffff; + } + + if (!is_nec && modrm_cycs_post[rmdat & 0xc7]) + do_cycles(modrm_cycs_post[rmdat & 0xc7]); + } +} + +static void +decode(void) +{ + uint8_t op_f; + uint8_t prefix = 0; + + if (halted) + opcode = 0xf4; + else + opcode = biu_pfq_fetchb_common(); + + modrm_loaded = 0; + + while (1) { + prefix = 0; + + switch (opcode) { + case 0x0f: /* NEC/186 */ + if (is_nec) { + in_0f = 1; + prefix = 1; + } + break; + case 0x26: /* ES: */ + case 0x2e: /* CS: */ + case 0x36: /* SS: */ + case 0x3e: /* DS: */ + ovr_seg = opseg[(opcode >> 3) & 0x03]; + prefix = 1; + break; + case 0x64: /* REPNC */ + case 0x65: /* REPC */ + if (is_nec) { + in_rep = (opcode == 0x64 ? 1 : 2); + rep_c_flag = 1; + prefix = 1; + } + break; + case 0xf0: + case 0xf1: /* LOCK - F1 is alias */ + in_lock = 1; + prefix = 1; + break; + case 0xf2: /* REPNE */ + case 0xf3: /* REPE */ + in_rep = (opcode == 0xf2 ? 1 : 2); + rep_c_flag = 0; + prefix = 1; + break; + default: + break; + } + + if (prefix == 0) + break; + + do_cycle(); + + opcode = biu_pfq_fetchb_common(); + } + + if (is_nec) { + if (in_0f) + op_f = (uint8_t) opf_0f[opcode]; + else + op_f = (uint8_t) opf_nec[opcode]; + } else + op_f = (uint8_t) opf[opcode]; + + if (op_f & OP_GRP) { + do_mod_rm(); + modrm_loaded = 1; + + op_f |= (OP_MRM | OP_EA); + + if (opcode >= 0xf0) { + op_f |= OP_DELAY; + group_delay = 1; + } + } + + if (!modrm_loaded && (op_f & OP_MRM)) { + do_mod_rm(); + modrm_loaded = 1; + } + + if (modrm_loaded && !(op_f & OP_EA)) { + if (is_nec) + do_cycle(); + else { + if (opcode == 0x8f) { + if (cpu_mod == 3) + do_cycles_i(2); + } else + do_cycles_i(2); + } + } +} + +static void +string_op(int bits) +{ + uint16_t tmpa; + uint16_t old_ax; + + if ((opcode & 0xf0) == 0x60) switch (opcode & 0x0e) { + case 0x0c: + old_ax = AX; + cpu_data = DX; + cpu_state.eaaddr = cpu_data; + cpu_io_vx0(bits, 0, cpu_state.eaaddr); + cpu_data = AX; + stos(bits); + AX = old_ax; + break; + case 0x0e: + old_ax = AX; + lods(bits); + set_accum(bits, cpu_data); + cpu_data = DX; + do_cycle_i(); + /* biu_io_write_u16() */ + cpu_state.eaaddr = cpu_data; + cpu_io_vx0(bits, 1, cpu_state.eaaddr); + AX = old_ax; + break; + } else switch (opcode & 0x0e) { + case 0x04: + lods(bits); + do_cycle_i(); + stos(bits); + break; + case 0x06: + do_cycle_i(); + if (is_nec) { + if (in_rep) { + lods_di(bits); + tmpa = cpu_data; + lods(bits); + } else { + lods(bits); + tmpa = cpu_data; + lods_di(bits); + } + } else { + lods(bits); + tmpa = cpu_data; + do_cycles_i(2); + lods_di(bits); + do_cycles_i(3); + } + + cpu_src = cpu_data; + cpu_dest = tmpa; + sub(bits); + break; + case 0x0e: + tmpa = AX; + do_cycles_i(2); + lods_di(bits); + do_cycles_i(3); + + cpu_src = cpu_data; + cpu_dest = tmpa; + sub(bits); + break; + case 0x0a: + cpu_data = AX; + stos(bits); + break; + case 0x0c: + lods(bits); + set_accum(bits, cpu_data); + break; + } +} + +static int do_print = 1; + +static void +execvx0_0f(void) +{ + uint8_t bit; + uint8_t odd; + uint8_t nibbles_count; + uint8_t destcmp; + uint8_t destbyte; + uint8_t srcbyte; + uint8_t nibble_result; + uint8_t temp_val; + uint8_t temp_al; + uint8_t bit_length; + uint8_t bit_offset; + int8_t nibble_result_s; + int bits; + uint32_t i; + uint32_t carry; + uint32_t nibble; + uint32_t srcseg; + uint32_t byteaddr; + + switch (opcode) { + case 0x10: /* TEST1 r8/m8, CL*/ + case 0x11: /* TEST1 r16/m16, CL*/ + case 0x18: /* TEST1 r8/m8, imm3 */ + case 0x19: /* TEST1 r16/m16, imm4 */ + bits = 8 << (opcode & 0x1); + do_cycles(2); + + bit = (opcode & 0x8) ? biu_pfq_fetchb() : CL; + bit &= ((1 << (3 + (opcode & 0x1))) - 1); + read_ea(0, bits); + + set_zf_ex(!(cpu_data & (1 << bit))); + cpu_state.flags &= ~(V_FLAG | C_FLAG); + break; + + case 0x12: /* CLR1 r8/m8, CL*/ + case 0x13: /* CLR1 r16/m16, CL*/ + case 0x1a: /* CLR1 r8/m8, imm3 */ + case 0x1b: /* CLR1 r16/m16, imm4 */ + bits = 8 << (opcode & 0x1); + do_cycles(2); + + bit = (opcode & 0x8) ? biu_pfq_fetchb() : CL; + bit &= ((1 << (3 + (opcode & 0x1))) - 1); + read_ea(0, bits); + + if (bits == 8) + seteab((cpu_data & 0xff) & ~(1 << bit)); + else + seteaw((cpu_data & 0xffff) & ~(1 << bit)); + break; + + case 0x14: /* SET1 r8/m8, CL*/ + case 0x15: /* SET1 r16/m16, CL*/ + case 0x1c: /* SET1 r8/m8, imm3 */ + case 0x1d: /* SET1 r16/m16, imm4 */ + bits = 8 << (opcode & 0x1); + do_cycles(2); + + bit = (opcode & 0x8) ? biu_pfq_fetchb() : CL; + bit &= ((1 << (3 + (opcode & 0x1))) - 1); + read_ea(0, bits); + + if (bits == 8) + seteab((cpu_data & 0xff) | (1 << bit)); + else + seteaw((cpu_data & 0xffff) | (1 << bit)); + break; + + case 0x16: /* NOT1 r8/m8, CL*/ + case 0x17: /* NOT1 r16/m16, CL*/ + case 0x1e: /* NOT1 r8/m8, imm3 */ + case 0x1f: /* NOT1 r16/m16, imm4 */ + bits = 8 << (opcode & 0x1); + do_cycles(2); + + bit = (opcode & 0x8) ? (biu_pfq_fetchb()) : (CL); + bit &= ((1 << (3 + (opcode & 0x1))) - 1); + read_ea(0, bits); + + if (bits == 8) + seteab((cpu_data & 0xff) ^ (1 << bit)); + else + seteaw((cpu_data & 0xffff) ^ (1 << bit)); + break; + + case 0x20: /* ADD4S */ + odd = !!(CL % 2); + zero = 1; + nibbles_count = CL - odd; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; + + do_cycles(4); + + for (i = 0; i < ((nibbles_count / 2) + odd); i++) { + do_cycles(19); + destcmp = read_mem_b((es) + DI + i); + + for (nibble = 0; nibble < 2; nibble++) { + destbyte = destcmp >> (nibble ? 4 : 0); + srcbyte = read_mem_b(srcseg + SI + i) >> (nibble ? 4 : 0); + destbyte &= 0xF; + srcbyte &= 0xF; + nibble_result = (i == (nibbles_count / 2) && nibble == 1) ? (destbyte + carry) : + ((uint8_t) (destbyte)) + ((uint8_t) (srcbyte)) + ((uint32_t) carry); + carry = 0; + + while (nibble_result >= 10) { + nibble_result -= 10; + carry++; + } + + if (zero != 0 || (i == (nibbles_count / 2) && nibble == 1)) + zero = (nibble_result == 0); + + destcmp = ((destcmp & (nibble ? 0x0F : 0xF0)) | (nibble_result << (4 * nibble))); + } + + write_mem_b(es + DI + i, destcmp); + } + + set_cf(!!carry); + set_zf(!!zero); + break; + + case 0x22: /* SUB4S */ + odd = !!(CL % 2); + zero = 1; + nibbles_count = CL - odd; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; + + do_cycles(4); + + for (i = 0; i < ((nibbles_count / 2) + odd); i++) { + do_cycles(19); + destcmp = read_mem_b((es) + DI + i); + + for (nibble = 0; nibble < 2; nibble++) { + destbyte = destcmp >> (nibble ? 4 : 0); + srcbyte = read_mem_b(srcseg + SI + i) >> (nibble ? 4 : 0); + destbyte &= 0xF; + srcbyte &= 0xF; + nibble_result_s = (i == (nibbles_count / 2) && nibble == 1) ? ((int8_t) destbyte - (int8_t) carry) : + ((int8_t) (destbyte)) - ((int8_t) (srcbyte)) - ((int8_t) carry); + carry = 0; + + while (nibble_result_s < 0) { + nibble_result_s += 10; + carry++; + } + + if (zero != 0 || (i == (nibbles_count / 2) && nibble == 1)) + zero = (nibble_result_s == 0); + + destcmp = ((destcmp & (nibble ? 0x0F : 0xF0)) | (nibble_result_s << (4 * nibble))); + } + + write_mem_b(es + DI + i, destcmp); + } + + set_cf(!!carry); + set_zf(!!zero); + break; + + case 0x26: /* CMP4S */ + odd = !!(CL % 2); + zero = 1; + nibbles_count = CL - odd; + i = 0; + carry = 0; + nibble = 0; + srcseg = ovr_seg ? *ovr_seg : ds; + + do_cycles(4); + + for (i = 0; i < ((nibbles_count / 2) + odd); i++) { + do_cycles(19); + destcmp = read_mem_b((es) + DI + i); + + for (nibble = 0; nibble < 2; nibble++) { + destbyte = destcmp >> (nibble ? 4 : 0); + srcbyte = read_mem_b(srcseg + SI + i) >> (nibble ? 4 : 0); + destbyte &= 0xF; + srcbyte &= 0xF; + nibble_result_s = ((int8_t) (destbyte)) - ((int8_t) (srcbyte)) - ((int8_t) carry); + carry = 0; + + while (nibble_result_s < 0) { + nibble_result_s += 10; + carry++; + } + + if (zero != 0 || (i == (nibbles_count / 2) && nibble == 1)) + zero = (nibble_result_s == 0); + + destcmp = ((destcmp & (nibble ? 0x0F : 0xF0)) | (nibble_result_s << (4 * nibble))); + } + } + + set_cf(!!carry); + set_zf(!!zero); + break; + + case 0x28: /* ROL4 r/m */ + do_cycles(20); + + temp_val = geteab(); + temp_al = AL; + + temp_al &= 0x0f; + temp_al |= (temp_val & 0xf0); + temp_val = (temp_al & 0x0f) | ((temp_val & 0x0f) << 4); + temp_al >>= 4; + temp_al &= 0x0f; + seteab(temp_val); + AL = temp_al; + break; + + case 0x2a: /* ROR4 r/m */ + do_cycles(20); + + temp_val = geteab(); + temp_al = AL; + + AL = temp_val & 0x0f; + temp_val = (temp_val >> 4) | ((temp_al & 0x0f) << 4); + + seteab(temp_val); + break; + + case 0x31: /* INS reg1, reg2 */ + case 0x39: /* INS reg8, imm4 */ + bit_length = ((opcode & 0x8) ? (biu_pfq_fetchb() & 0x0f) : (getr8(cpu_reg) & 0x0f)) + 1; + bit_offset = getr8(cpu_rm) & 0x0f; + byteaddr = (es) + DI; + i = 0; + + if (bit_offset >= 8) { + DI++; + byteaddr++; + bit_offset -= 8; + } + + for (i = 0; i < bit_length; i++) { + byteaddr = (es) + DI; + writememb(es, DI, (read_mem_b(byteaddr) & ~(1 << (bit_offset))) | ((!!(AX & (1 << i))) << bit_offset)); + bit_offset++; + + if (bit_offset == 8) { + DI++; + bit_offset = 0; + } + } + + setr8(cpu_rm, bit_offset); + break; + + case 0x33: /* EXT reg1, reg2 */ + case 0x3b: /* EXT reg8, imm4 */ + bit_length = ((opcode & 0x8) ? (biu_pfq_fetchb() & 0x0f) : (getr8(cpu_reg) & 0x0f)) + 1; + bit_offset = getr8(cpu_rm) & 0x0f; + byteaddr = (ds) + SI; + i = 0; + + if (bit_offset >= 8) { + SI++; + byteaddr++; + bit_offset -= 8; + } + + AX = 0; + + for (i = 0; i < bit_length; i++) { + byteaddr = (ds) + SI; + AX |= (!!(readmemb(ds, SI) & (1 << bit_offset))) << i; + bit_offset++; + + if (bit_offset == 8) { + SI++; + bit_offset = 0; + } + } + + setr8(cpu_rm, bit_offset); + break; + + case 0xff: /* BRKEM */ + interrupt_brkem(biu_pfq_fetchb()); + break; + + default: + do_cycles_nx_i(2); /* Guess, based on NOP. */ + break; + } +} + +static void +execvx0_6x(uint16_t *jump) +{ + uint16_t lowbound; + uint16_t highbound; + uint16_t regval; + uint16_t wordtopush; + uint16_t immediate; + uint16_t tempw; + int bits; + int32_t templ; + + switch (opcode) { + case 0x60: /* PUSHA/PUSH R */ + writememw(ss, ((SP - 2) & 0xffff), AX); + biu_state_set_eu(); + writememw(ss, ((SP - 4) & 0xffff), CX); + biu_state_set_eu(); + writememw(ss, ((SP - 6) & 0xffff), DX); + biu_state_set_eu(); + writememw(ss, ((SP - 8) & 0xffff), BX); + biu_state_set_eu(); + writememw(ss, ((SP - 10) & 0xffff), SP); + biu_state_set_eu(); + writememw(ss, ((SP - 12) & 0xffff), BP); + biu_state_set_eu(); + writememw(ss, ((SP - 14) & 0xffff), SI); + biu_state_set_eu(); + writememw(ss, ((SP - 16) & 0xffff), DI); + SP -= 16; + break; + + case 0x61: /* POPA/POP R */ + DI = readmemw(ss, ((SP) & 0xffff)); + biu_state_set_eu(); + SI = readmemw(ss, ((SP + 2) & 0xffff)); + biu_state_set_eu(); + BP = readmemw(ss, ((SP + 4) & 0xffff)); + biu_state_set_eu(); + BX = readmemw(ss, ((SP + 8) & 0xffff)); + biu_state_set_eu(); + DX = readmemw(ss, ((SP + 10) & 0xffff)); + biu_state_set_eu(); + CX = readmemw(ss, ((SP + 12) & 0xffff)); + biu_state_set_eu(); + AX = readmemw(ss, ((SP + 14) & 0xffff)); + SP += 16; + break; + + case 0x62: /* BOUND r/m */ + lowbound = 0; + highbound = 0; + regval = 0; + + lowbound = readmemw(easeg, cpu_state.eaaddr); + highbound = readmemw(easeg, cpu_state.eaaddr + 2); + regval = get_reg(cpu_reg); + + if ((lowbound > regval) || (highbound < regval)) { + sw_int(5); + *jump = 1; + } + break; + + case 0x63: + if (is_nec) { + /* read_operand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + tempw = cpu_state.pc; + geteaw(); + do_cycles(60); + } + break; + + case 0x64: + case 0x65: + if (!is_nec) { + do_cycles_nx_i(2); /* Guess, based on NOP. */ + } + break; + + case 0x66 ... 0x67: /* FPO2 - NEC FPU instructions. */ + /* read_operand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + tempw = cpu_state.pc; + geteaw(); + /* fpu_op() */ + cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on + the 286+ core, but not here. */ + break; + + case 0x68: + wordtopush = biu_pfq_fetchw(); + push(&wordtopush); + break; + + case 0x69: + bits = 16; + read_ea(0, 16); + immediate = biu_pfq_fetchw(); + + templ = ((int) cpu_data) * ((int) immediate); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + set_reg(cpu_reg, templ & 0xffff); + do_cycles((cpu_mod == 3) ? 20 : 26); + break; + + case 0x6a: + wordtopush = sign_extend(biu_pfq_fetchb()); + push(&wordtopush); + break; + + case 0x6b: /* IMUL reg16,reg16/mem16,imm8 */ + read_ea(0, 16); + immediate = biu_pfq_fetchb(); + immediate = geteaw(); + if (immediate & 0x80) + immediate |= 0xff00; + + templ = ((int) cpu_data) * ((int) immediate); + if ((templ >> 15) != 0 && (templ >> 15) != -1) + cpu_state.flags |= C_FLAG | V_FLAG; + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + set_reg(cpu_reg, templ & 0xffff); + do_cycles((cpu_mod == 3) ? 24 : 30); + break; + + case 0x6c: + case 0x6d: /* INM dst, DW/INS dst, DX */ + bits = 8 << (opcode & 1); + if (rep_start()) { + string_op(bits); + do_cycle_i(); + + if (in_rep != 0) { + completed = 0; + repeating = 1; + + do_cycle_i(); + if (irq_pending()) { + do_cycle_i(); + rep_interrupt(); + } + + do_cycle_i(); + /* decrement_register16() */ + CX--; + if (CX == 0) + rep_end(); + else + do_cycle_i(); + } else + do_cycle_i(); + } + break; + + case 0x6e: + case 0x6f: /* OUTM DW, src/OUTS DX, src */ + bits = 8 << (opcode & 1); + if (rep_start()) { + string_op(bits); + do_cycles_i(3); + + if (in_rep != 0) { + completed = 0; + repeating = 1; + + do_cycle_i(); + /* decrement_register16() */ + CX--; + + if (irq_pending()) { + do_cycles_i(2); + rep_interrupt(); + } else { + do_cycles_i(2); + + if (CX == 0) + rep_end(); + else + do_cycle_i(); + } + } + } + break; + + default: + do_cycles_nx_i(2); /* Guess, based on NOP. */ + break; + } +} + +/* Executes a single instruction. */ +void +execute_instruction(void) +{ + uint8_t temp = 0; + uint8_t tempb; + uint8_t nests; + + int8_t rel8; + int8_t temps; + + uint16_t addr; + uint16_t jump = 0; + uint16_t new_cs; + uint16_t new_ip; + uint16_t tempw; + uint16_t zero_cond; + uint16_t old_cs; + uint16_t old_ip; + uint16_t old_flags; + uint16_t prod16; + uint16_t tempw_int; + uint16_t size; + uint16_t tempbp; + uint16_t src16; + + int16_t rel16; + int16_t temps16; + + uint32_t prod32; + uint32_t templ; + uint32_t templ2 = 0; + + int bits; + int negate; + int tempws = 0; + int tempws2 = 0; + + completed = 1; + + if (nx) { + do_cycle(); + nx = 0; + } else if (!modrm_loaded) + do_cycle(); + + if (group_delay) { + group_delay = 0; + do_cycle(); + nx = 0; + } + + if (!is_nec && (opcode >= 0xc0) && (opcode <= 0xc1)) + opcode |= 0x02; + + if (is_nec && !(cpu_state.flags & MD_FLAG)) { + i8080_step(&emulated_processor); + set_if(emulated_processor.iff); + if (retem) + jump = 1; + retem = 0; + do_cycles(emulated_processor.cyc); + emulated_processor.cyc = 0; + } else if (is_nec && in_0f) + execvx0_0f(); + else if (is_nec && ((opcode & 0xf0) == 0x60)) + execvx0_6x(&jump); + else switch (opcode) { + case 0x00: /* ADD r/m8, r8; r8, r/m8; al, imm8 */ + case 0x02: + case 0x04: + case 0x08: /* OR r/m8, r8; r8, r/m8; al, imm8 */ + case 0x0a: + case 0x0c: + case 0x10: /* ADC r/m8, r8; r8, r/m8; al, imm8 */ + case 0x12: + case 0x14: + case 0x18: /* SBB r/m8, r8; r8, r/m8; al, imm8 */ + case 0x1a: + case 0x1c: + case 0x20: /* AND r/m8, r8; r8, r/m8; al, imm8 */ + case 0x22: + case 0x24: + case 0x28: /* SUB r/m8, r8; r8, r/m8; al, imm8 */ + case 0x2a: + case 0x2c: + case 0x30: /* XOR r/m8, r8; r8, r/m8; al, imm8 */ + case 0x32: + case 0x34: + bits = 8; + /* read_operand8() */ + if (opcode & 0x04) { + cpu_data = biu_pfq_fetch(); + cpu_dest = get_accum(bits); /* AX/AL */ + cpu_src = cpu_data; + } else { + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + tempw = get_ea(); + if (opcode & 2) { + cpu_dest = get_reg(cpu_reg); + cpu_src = tempw; + } else { + cpu_dest = tempw; + cpu_src = get_reg(cpu_reg); + } + } + do_cycles_nx_i(2); + if (!(opcode & 0x06) && (cpu_mod != 3)) + do_cycles_i(2); + + /* math_op8() */ + math_op((opcode >> 3) & 7); + /* write_operand8() */ + if (opcode & 0x04) + set_accum(bits, cpu_data); + else { + if (opcode & 2) + set_reg(cpu_reg, cpu_data); + else + set_ea(cpu_data); + } + break; + + case 0x01: /* ADD r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x03: + case 0x05: + case 0x09: /* OR r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x0b: + case 0x0d: + case 0x11: /* ADC r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x13: + case 0x15: + case 0x19: /* SBB r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x1b: + case 0x1d: + case 0x21: /* AND r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x23: + case 0x25: + case 0x29: /* SUB r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x2b: + case 0x2d: + case 0x31: /* XOR r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x33: + case 0x35: + bits = 16; + nx = 1; + /* read_operand16() */ + if (opcode & 0x04) { + cpu_data = biu_pfq_fetch(); + cpu_dest = get_accum(bits); /* AX/AL */ + cpu_src = cpu_data; + } else { + if (cpu_mod != 3) + do_cycles_i(is_nec ? 1 : 2); /* load_operand() */ + tempw = get_ea(); + if (opcode & 2) { + cpu_dest = get_reg(cpu_reg); + cpu_src = tempw; + } else { + cpu_dest = tempw; + cpu_src = get_reg(cpu_reg); + } + } + do_cycles_nx_i(2); + if (!(opcode & 0x06) && (cpu_mod != 3)) + do_cycles_i(2); + + /* math_op16() */ + math_op((opcode >> 3) & 7); + /* write_operand16() */ + if (opcode & 0x04) + set_accum(bits, cpu_data); + else { + if (opcode & 0x02) + set_reg(cpu_reg, cpu_data); + else + set_ea(cpu_data); + } + break; + + case 0x06: + case 0x0e: + case 0x16: + case 0x1e: /* PUSH seg */ + do_cycles_i(3); + push(&(_opseg[(opcode >> 3) & 0x03]->seg)); + break; + + case 0x07: + case 0x17: + case 0x1f: /* POP seg */ + load_seg(pop(), _opseg[(opcode >> 3) & 0x03]); + /* All POP segment instructions suppress interrupts for one instruction. */ + noint = 1; + break; + + case 0x0f: + if (!is_nec) { + load_cs(pop()); + /* All POP segment instructions suppress interrupts for one instruction. */ + noint = 1; + } + break; + + case 0x26: /* ES: */ + case 0x2e: /* CS: */ + case 0x36: /* SS: */ + case 0x3e: /* DS: */ + break; + + case 0x27: /* DAA */ + do_cycles_nx_i(3); + daa(); + break; + + case 0x2f: /* DAS */ + do_cycles_nx_i(3); + das(); + break; + + case 0x37: /* AAA */ + aaa(); + break; + + case 0x38: /* CMP r/m8, r8; r8, r/m8; al, imm8 */ + case 0x3a: + case 0x3c: + bits = 8; + /* read_operand8() */ + if (opcode & 0x04) { + cpu_data = biu_pfq_fetch(); + cpu_dest = get_accum(bits); /* AX/AL */ + cpu_src = cpu_data; + } else { + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + tempw = get_ea(); + if (opcode & 2) { + cpu_dest = get_reg(cpu_reg); + cpu_src = tempw; + } else { + cpu_dest = tempw; + cpu_src = get_reg(cpu_reg); + } + } + + do_cycles_nx_i(2); + + /* math_op8() */ + math_op(7); + break; + + case 0x39: /* CMP r/m16, r16; r16, r/m16; ax, imm16 */ + case 0x3b: + case 0x3d: + bits = 16; + /* read_operand16() */ + if (opcode & 0x04) { + cpu_data = biu_pfq_fetch(); + cpu_dest = get_accum(bits); /* AX/AL */ + cpu_src = cpu_data; + } else { + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + tempw = get_ea(); + if (opcode & 2) { + cpu_dest = get_reg(cpu_reg); + cpu_src = tempw; + } else { + cpu_dest = tempw; + cpu_src = get_reg(cpu_reg); + } + } + + do_cycles_nx_i((opcode == 0x3d) ? 1 : 2); + + /* math_op16() */ + math_op(7); + break; + + case 0x3f: /*AAS*/ + aas(); + break; + + case 0x40 ... 0x47: /* INC r16 */ + /* read_operand16() */ + cpu_dest = cpu_state.regs[opcode & 7].w; + cpu_src = 1; + bits = 16; + /* math_op16() */ + cpu_data = cpu_dest + cpu_src; + set_of_add(bits); + do_af(); + set_pzs(16); + /* write_operand16() */ + cpu_state.regs[opcode & 7].w = cpu_data; + + do_cycles_nx(1); + break; + + case 0x48 ... 0x4f: /* DEC r16 */ + /* read_operand16() */ + cpu_dest = cpu_state.regs[opcode & 7].w; + cpu_src = 1; + bits = 16; + /* math_op16() */ + cpu_data = cpu_dest - cpu_src; + set_of_sub(bits); + do_af(); + set_pzs(16); + /* write_operand16() */ + cpu_state.regs[opcode & 7].w = cpu_data; + + do_cycles_nx(1); + break; + + case 0x50 ... 0x57: /* PUSH r16 */ + do_cycles_i(3); + + push(&(cpu_state.regs[opcode & 0x07].w)); + break; + + case 0x58 ... 0x5f: /* POP r16 */ + cpu_state.regs[opcode & 0x07].w = pop(); + do_cycle_nx_i(); + break; + + case 0x60 ... 0x7f: /* JMP rel8 */ + switch ((opcode >> 1) & 0x07) { + case 0x00: + jump = cpu_state.flags & V_FLAG; + break; + case 0x01: + jump = cpu_state.flags & C_FLAG; + break; + case 0x02: + jump = cpu_state.flags & Z_FLAG; + break; + case 0x03: + jump = cpu_state.flags & (C_FLAG | Z_FLAG); + break; + case 0x04: + jump = cpu_state.flags & N_FLAG; + break; + case 0x05: + jump = cpu_state.flags & P_FLAG; + break; + case 0x06: + jump = (!!(cpu_state.flags & N_FLAG)) != (!!(cpu_state.flags & V_FLAG)); + break; + case 0x07: + jump = (cpu_state.flags & Z_FLAG) || + ((!!(cpu_state.flags & N_FLAG)) != (!!(cpu_state.flags & V_FLAG))); + break; + } + if (opcode & 1) + jump = !jump; + + rel8 = (int8_t) biu_pfq_fetchb(); + new_ip = cpu_state.pc + rel8; + if (!is_nec) + do_cycle_i(); + + if (jump) + reljmp(new_ip, 1); + break; + + case 0x80: /* ADD/OR/ADC/SBB/AND/SUB/XOR/CMP r/m8, imm8 */ + case 0x82: + bits = 8; + /* read_opreand8() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = get_ea(); + cpu_dest = cpu_data; + cpu_src = biu_pfq_fetchb() | 0xff00; + + do_cycle_nx(); + math_op((rmdat & 0x38) >> 3); + + if (cpu_mod != 3) + do_cycles_i(2); + + /* write_operand8() */ + if (cpu_alu_op != 7) + set_ea(cpu_data); + break; + + case 0x81: /* ADD/OR/ADC/SBB/AND/SUB/XOR/CMP r/m16, imm16 */ + bits = 16; + /* read_opreand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = get_ea(); + cpu_dest = cpu_data; + cpu_src = biu_pfq_fetchw(); + + do_cycle_nx(); + math_op((rmdat & 0x38) >> 3); + + if (cpu_mod != 3) { + if (cpu_alu_op != 7) + do_cycles_i(2); + else { + do_cycles_nx_i(2); + } + } + + /* write_operand16() */ + if (cpu_alu_op != 7) + set_ea(cpu_data); + break; + + case 0x83: /* ADD/OR/ADC/SBB/AND/SUB/XOR/CMP r/m16, imm8 (sign-extended) */ + bits = 16; + /* read_opreand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = get_ea(); + cpu_dest = cpu_data; + cpu_src = sign_extend(biu_pfq_fetchb()); + + do_cycle_nx(); + math_op((rmdat & 0x38) >> 3); + + if (cpu_mod != 3) + do_cycles_i(2); + + /* write_operand16() */ + if (cpu_alu_op != 7) + set_ea(cpu_data); + break; + + case 0x84: /* TEST r/m8, r8 */ + bits = 8; + /* read_operand8() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = get_ea(); + + /* math_op8() */ + test(bits, cpu_data, get_reg(cpu_reg)); + + do_cycles_nx_i(2); + break; + + case 0x85: /* TEST r/m16, r16 */ + bits = 16; + /* read_operand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = get_ea(); + + /* math_op16() */ + test(bits, cpu_data, get_reg(cpu_reg)); + + do_cycles_nx_i(2); + break; + + case 0x86: /* XHG r8, r/m8 */ + bits = 8; + /* read_operand8() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = get_ea(); + cpu_src = get_reg(cpu_reg); + + do_cycles_nx(3); + + if (cpu_mod != 3) + do_cycles(2); + + /* write_operand8() */ + set_reg(cpu_reg, cpu_data); + set_ea(cpu_src); + break; + + case 0x87: /* XCHG r16, r/m16 */ + bits = 16; + /* read_operand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = get_ea(); + cpu_src = get_reg(cpu_reg); + + do_cycles_nx(3); + + if (cpu_mod != 3) + do_cycles(2); + + /* write_operand16() */ + set_reg(cpu_reg, cpu_data); + set_ea(cpu_src); + break; + + case 0x88: /* MOV r/m8, r8; MOV r8, r/m8 */ + case 0x8a: + bits = 8; + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + do_cycle_nx(); + /* read_operand8() */ + if (opcode == 0x88) + tempb = get_reg(cpu_reg); + else + tempb = get_ea(); + + if ((opcode == 0x88) && (cpu_mod != 3)) + do_cycles_i(2); + + /* write_operand8() */ + if (opcode == 0x88) + set_ea(tempb); + else + set_reg(cpu_reg, tempb); + break; + + case 0x89: /* MOV r/m16, r16; MOV r16, r/m16 */ + case 0x8b: + bits = 16; + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + do_cycle_nx(); + /* read_operand16() */ + if (opcode == 0x89) + tempw = get_reg(cpu_reg); + else + tempw = get_ea(); + + if ((opcode == 0x89) && (cpu_mod != 3)) + do_cycles_i(2); + + /* write_operand16() */ + if (opcode == 0x89) + set_ea(tempw); + else + set_reg(cpu_reg, tempw); + break; + + case 0x8c: /* MOV r/m16, SReg; MOV SReg, r/m16 */ + case 0x8e: + bits = 16; + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + if ((opcode == 0x8c) && (cpu_mod != 3)) + do_cycle_i(); + /* read_operand16() */ + if (opcode == 0x8c) + tempw = _opseg[(rmdat & 0x18) >> 3]->seg; + else + tempw = geteaw(); + /* write_operand16() */ + if (opcode == 0x8c) + seteaw(tempw); + else { + if ((rmdat & 0x18) == 0x08) + load_cs(tempw); + else + load_seg(tempw, _opseg[(rmdat & 0x18) >> 3]); + if (((rmdat & 0x18) >> 3) == 2) + noint = 1; + } + break; + + case 0x8d: /* LEA */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_state.regs[cpu_reg].w = cpu_state.eaaddr; + break; + + case 0x8f: /* POP r/m16 */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + do_cycle_i(); + /* pop_u16() */ + cpu_src = cpu_state.eaaddr; + cpu_data = pop(); + do_cycle_i(); + if (cpu_mod != 3) + do_cycles_i(2); + /* write_operand16() */ + cpu_state.eaaddr = cpu_src; + seteaw(cpu_data); + break; + + case 0x90 ... 0x97: /* XCHG AX, r */ + cpu_data = cpu_state.regs[opcode & 7].w; + do_cycles_nx_i(2); + cpu_state.regs[opcode & 7].w = AX; + AX = cpu_data; + break; + + case 0x98: /* CBW */ + sign_extend_al(); + break; + + case 0x99: /* CWD */ + sign_extend_ax(); + break; + + case 0x9a: /* CALLF */ + /* read_operand_faraddr() */ + new_ip = biu_pfq_fetchw(); + new_cs = biu_pfq_fetchw(); + + farcall(new_cs, new_ip, 1); + + jump = 1; + break; + + case 0x9b: /* WAIT */ + do_cycles(3); + break; + + case 0x9c: /* PUSHF */ + do_cycles(3); + /* push_flags() */ + if (is_nec) + tempw = (cpu_state.flags & 0x8fd7) | 0x7000; + else + tempw = (cpu_state.flags & 0x0fd7) | 0xf000; + push(&tempw); + break; + + case 0x9d: /* POPF */ + /* pop_flags() */ + if (is_nec && cpu_md_write_disable) + cpu_state.flags = pop() | 0x8002; + else + cpu_state.flags = pop() | 0x0002; + sync_to_i8080(); + break; + + case 0x9e: /* SAHF */ + /* store_flags() */ + cpu_state.flags = (cpu_state.flags & 0xff02) | AH; + break; + + case 0x9f: /*LAHF*/ + /* load_flags() */ + /* set_register8() */ + AH = cpu_state.flags & 0xd7; + break; + + case 0xa0: /* MOV al, offset8 */ + bits = 8; + /* read_operand8() */ + cpu_state.eaaddr = biu_pfq_fetchw(); + tempb = readmem(ovr_seg ? *ovr_seg : ds); + /* set_register8() */ + set_accum(bits, tempb); + break; + + case 0xa1: /* MOV al, offset16 */ + bits = 16; + /* read_operand16() */ + cpu_state.eaaddr = biu_pfq_fetchw(); + tempw = readmem(ovr_seg ? *ovr_seg : ds); + /* set_register16() */ + set_accum(bits, tempw); + break; + + case 0xa2: /* MOV offset8, Al */ + bits = 8; + tempb = get_accum(bits); + /* write_operand8() */ + cpu_state.eaaddr = biu_pfq_fetchw(); + writemem((ovr_seg ? *ovr_seg : ds), tempb); + break; + + case 0xa3: /* MOV offset16, AX */ + bits = 16; + tempw = get_accum(bits); + /* write_operand16() */ + cpu_state.eaaddr = biu_pfq_fetchw(); + writemem((ovr_seg ? *ovr_seg : ds), tempw); + break; + + case 0xa4: /* MOVSB & MOVSW */ + case 0xa5: + bits = 8 << (opcode & 1); + + if (rep_start()) { + string_op(bits); + do_cycle_i(); + + if (in_rep != 0) { + completed = 0; + repeating = 1; + + /* decrement_register16() */ + CX--; + + if (irq_pending()) { + do_cycles_i(2); + rep_interrupt(); + } else { + do_cycles_i(2); + + if (CX == 0) + rep_end(); + else + do_cycle_i(); + } + } else + do_cycle_i(); + } + break; + + case 0xa6: /* CMPSB, CMPSW, SCASB, SCASW */ + case 0xa7: + case 0xae: + case 0xaf: + bits = 8 << (opcode & 1); + if (rep_start()) { + string_op(bits); + + if (in_rep) { + uint8_t end = 0; + + completed = 0; + repeating = 1; + + do_cycle_i(); + /* decrement_register16() */ + CX--; + + if ((!!(cpu_state.flags & (rep_c_flag ? C_FLAG : Z_FLAG))) == (in_rep == 1)) { + rep_end(); + do_cycle_i(); + end = 1; + } + + if (!end) { + do_cycle_i(); + + if (irq_pending()) { + do_cycle_i(); + rep_interrupt(); + } + + do_cycle_i(); + if (CX == 0) + rep_end(); + else + do_cycle_i(); + } else + do_cycle_i(); + } + } + break; + + case 0xa8: /* TEST al, imm8 */ + bits = 8; + /* read_operand8() */ + cpu_data = biu_pfq_fetch(); + /* math_op8() */ + test(bits, get_accum(bits), cpu_data); + break; + + case 0xa9: /* TEST ax, imm16 */ + bits = 16; + /* read_operand16() */ + cpu_data = biu_pfq_fetch(); + /* math_op16() */ + test(bits, get_accum(bits), cpu_data); + break; + + case 0xaa: /* STOSB & STOSW */ + case 0xab: + bits = 8 << (opcode & 1); + if (rep_start()) { + string_op(bits); + do_cycle_i(); + + if (in_rep != 0) { + completed = 0; + repeating = 1; + + do_cycle_i(); + if (irq_pending()) { + do_cycle_i(); + rep_interrupt(); + } + + do_cycle_i(); + /* decrement_register16() */ + CX--; + if (CX == 0) + rep_end(); + else + do_cycle_i(); + } else + do_cycle_i(); + } + break; + + case 0xac: /* LODSB * LODSW */ + case 0xad: + bits = 8 << (opcode & 1); + if (rep_start()) { + string_op(bits); + do_cycles_i(3); + + if (in_rep != 0) { + completed = 0; + repeating = 1; + + do_cycle_i(); + /* decrement_register16() */ + CX--; + + if (irq_pending()) { + do_cycles_i(2); + rep_interrupt(); + } else { + do_cycles_i(2); + + if (CX == 0) + rep_end(); + else + do_cycle_i(); + } + } + } + break; + + case 0xb0 ... 0xb7: /* MOV r8, imm8 */ + bits = 8; + /* read_operand8() */ + tempb = biu_pfq_fetchb(); + /* set_register8() */ + if (opcode & 0x04) + cpu_state.regs[opcode & 0x03].b.h = tempb; + else + cpu_state.regs[opcode & 0x03].b.l = tempb; + do_cycle_i(); + break; + + case 0xb8 ... 0xbf: /* MOV r16, imm16 */ + bits = 16; + /* read_operand16() */ + tempw = biu_pfq_fetchw(); + /* set_register16() */ + cpu_state.regs[opcode & 0x07].w = tempw; + break; + + case 0xc0: /* rot imm8 */ + case 0xc1: + /* rot rm */ + bits = 8 << (opcode & 1); + if (cpu_mod != 3) + do_cycles_i(is_nec ? 1 : 2); /* load_operand() */ + /* read_operand() */ + cpu_data = get_ea(); + cpu_src = biu_pfq_fetchb(); + if (is186 && !is_nec) + cpu_src &= 0x1F; + do_cycles_i(6); + if (cpu_src > 0) { + for (uint8_t i = 0; i < cpu_src; i++) + do_cycles_i(4); + } + if (cpu_mod != 3) + do_cycle_i(); + /* bitshift_op() */ + while (cpu_src != 0) { + cpu_dest = cpu_data; + oldc = cpu_state.flags & C_FLAG; + switch (rmdat & 0x38) { + case 0x00: /* ROL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data <<= 1; + cpu_data |= ((cpu_state.flags & C_FLAG) ? 1 : 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x08: /* ROR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (cpu_state.flags & C_FLAG) + cpu_data |= (!(opcode & 1) ? 0x80 : 0x8000); + set_of_rotate(bits); + set_af(0); + break; + case 0x10: /* RCL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data = (cpu_data << 1) | (oldc ? 1 : 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x18: /* RCR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (oldc) + cpu_data |= (!(opcode & 0x01) ? 0x80 : 0x8000); + set_cf((cpu_dest & 1) != 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x20: /* SHL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data <<= 1; + set_of_rotate(bits); + set_af((cpu_data & 0x10) != 0); + set_pzs(bits); + break; + case 0x28: /* SHR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + case 0x30: /* SETMO - undocumented? */ + bitwise(bits, 0xffff); + set_cf(0); + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + case 0x38: /* SAR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (!(opcode & 1)) + cpu_data |= (cpu_dest & 0x80); + else + cpu_data |= (cpu_dest & 0x8000); + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + + default: + break; + } + --cpu_src; + } + + if (opcode <= 0xd1) { + if (cpu_mod != 3) + do_cycle_i(); + } + + /* write_operand() */ + set_ea(cpu_data); + break; + + case 0xc2: /* RETN imm16 */ + bits = 8; + cpu_src = biu_pfq_fetchw(); + do_cycle_i(); + new_ip = pop(); + biu_suspend_fetch(); + set_ip(new_ip); + + do_cycles_i(2); + biu_queue_flush(); + do_cycles_i(3); + + /* release() */ + SP += cpu_src; + + jump = 1; + break; + + case 0xc3: /* RETN */ + bits = 8; + new_ip = pop(); + biu_suspend_fetch(); + set_ip(new_ip); + do_cycle_i(); + biu_queue_flush(); + do_cycles_i(2); + + jump = 1; + break; + + case 0xc4: /* LES */ + case 0xc5: /* LDS */ + bits = 16; + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + + do_cycles_i(2); + + /* read_operand_farptr() */ + read_ea(1, bits); + cpu_state.regs[cpu_reg].w = cpu_data; + read_ea2(bits); + + /* write_operand16() */ + load_seg(cpu_data, (opcode & 0x01) ? &cpu_state.seg_ds : &cpu_state.seg_es); + break; + + case 0xc6: /* MOV r/m8, imm8 */ + bits = 8; + /* read_operand8() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = biu_pfq_fetch(); + do_cycles(2); + /* write_operand8() */ + set_ea(cpu_data); + break; + + case 0xc7: /* MOV r/m16, imm16 */ + bits = 16; + /* read_operand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + cpu_data = biu_pfq_fetch(); + do_cycle_i(); + /* write_operand16() */ + set_ea(cpu_data); + break; + + case 0xc8: /* RETF imm16 */ + if (is_nec) { + /* ENTER/PREPARE */ + tempw_int = 0; + size = biu_pfq_fetchw(); + nests = biu_pfq_fetchb(); + + push(&BP); + tempw_int = SP; + if (nests > 0) { + while (--nests) { + tempbp = 0; + BP -= 2; + tempbp = readmemw(ss, BP); + push(&tempbp); + } + push(&tempw_int); + } + BP = tempw_int; + SP -= size; + break; + } else + fallthrough; + case 0xca: + bits = 16; + /* read_operand16() */ + cpu_src = biu_pfq_fetchw(); + farret(1); + /* release() */ + SP += cpu_src; + do_cycle_i(); + jump = 1; + break; + + case 0xc9: /* RETF */ + if (is_nec) { + /* LEAVE/DISPOSE */ + SP = BP; + BP = pop(); + break; + } else + fallthrough; + case 0xcb: + bits = 16; + do_cycle_i(); + farret(1); + jump = 1; + break; + + case 0xcc: /* INT 3 */ + do_cycles_i(4); + int3(); + jump = 1; + break; + + case 0xcd: /* INT imm8 */ + /* read_operand8() */ + temp = biu_pfq_fetchb(); + do_cycle_i(); + sw_int(temp); + jump = 1; + break; + + case 0xce: /* INTO */ + if (cpu_state.flags & V_FLAG) { + sw_int(4); + jump = 1; + } + break; + + case 0xcf: /* IRET */ + iret_routine(); + if (is_nec && !(cpu_state.flags & MD_FLAG)) + sync_to_i8080(); + jump = 1; + break; + + case 0xd0: /* ROL, ROR, RCL, RCR, SHL, SHR, SAR: r/m 8, 0x01 */ + case 0xd1: /* ROL, ROR, RCL, RCR, SHL, SHR, SAR: r/m 16, 0x01 */ + case 0xd2: /* ROL, ROR, RCL, RCR, SHL, SHR, SAR: r/m 8, cl */ + case 0xd3: /* ROL, ROR, RCL, RCR, SHL, SHR, SAR: r/m 16, cl */ + /* rot rm */ + bits = 8 << (opcode & 1); + if (cpu_mod != 3) + do_cycles_i(is_nec ? 1 : 2); /* load_operand() */ + /* read_operand() */ + cpu_data = get_ea(); + if ((opcode & 2) == 0) + cpu_src = 1; + else + cpu_src = CL; + if (is186 && !is_nec) + cpu_src &= 0x1F; + if (opcode >= 0xd2) { + do_cycles_i(6); + if (CL > 0) { + for (uint8_t i = 0; i < CL; i++) + do_cycles_i(4); + } + if (cpu_mod != 3) + do_cycle_i(); + } + /* bitshift_op() */ + while (cpu_src != 0) { + cpu_dest = cpu_data; + oldc = cpu_state.flags & C_FLAG; + if (is_nec && ((rmdat & 0x38) == 0x30)) + rmdat &= 0xef; /* Make it 0x20, so it aliases to SHL. */ + switch (rmdat & 0x38) { + case 0x00: /* ROL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data <<= 1; + cpu_data |= ((cpu_state.flags & C_FLAG) ? 1 : 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x08: /* ROR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (cpu_state.flags & C_FLAG) + cpu_data |= (!(opcode & 1) ? 0x80 : 0x8000); + set_of_rotate(bits); + set_af(0); + break; + case 0x10: /* RCL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data = (cpu_data << 1) | (oldc ? 1 : 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x18: /* RCR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (oldc) + cpu_data |= (!(opcode & 0x01) ? 0x80 : 0x8000); + set_cf((cpu_dest & 1) != 0); + set_of_rotate(bits); + set_af(0); + break; + case 0x20: /* SHL */ + set_cf(top_bit(cpu_data, bits)); + cpu_data <<= 1; + set_of_rotate(bits); + set_af((cpu_data & 0x10) != 0); + set_pzs(bits); + break; + case 0x28: /* SHR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + case 0x30: /* SETMO - undocumented? */ + bitwise(bits, 0xffff); + set_cf(0); + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + case 0x38: /* SAR */ + set_cf((cpu_data & 1) != 0); + cpu_data >>= 1; + if (!(opcode & 1)) + cpu_data |= (cpu_dest & 0x80); + else + cpu_data |= (cpu_dest & 0x8000); + set_of_rotate(bits); + set_af(0); + set_pzs(bits); + break; + + default: + break; + } + --cpu_src; + } + + if (opcode <= 0xd1) { + if (cpu_mod != 3) + do_cycle_i(); + } + + /* write_operand() */ + set_ea(cpu_data); + break; + + case 0xd4: /* AAM */ + /* read_operand8() */ + cpu_src = biu_pfq_fetchb(); + + if (is_nec) { + if (!cpu_src) + cpu_src = 10; + AH = AL / cpu_src; + AL %= cpu_src; + cpu_data = AL; + set_pzs(8); + do_cycles(12); + } else { + /* Confirmed to be identical on V20/V30 to 808x, per + XTIDE working correctly on both (it uses AAM with + parameter other than 10. */ + /* aam() */ + if (x86_div(AL, 0)) { + cpu_data = AL; + set_pzs(8); + } + } + break; + + case 0xd5: /* AAD */ + /* read_operand8() */ + cpu_src = biu_pfq_fetchb(); + + if (is_nec) { + cpu_src = 10; + AL = (AH * cpu_src) + AL; + AH = 0; + cpu_data = AL; + set_pzs(8); + do_cycles(4); + } else { + if (is_nec) + cpu_src = 10; + /* aad() */ + mul(cpu_src, AH); + cpu_dest = AL; + cpu_src = cpu_data; + add(8); + AL = cpu_data; + AH = 0x00; + set_pzs(8); + } + break; + + case 0xd6: /* SALC */ + if (is_nec) { + do_cycles(14); + fallthrough; + } else { + AL = (cpu_state.flags & C_FLAG) ? 0xff : 0x00; + break; + } + case 0xd7: /* XLAT */ + do_cycles_i(3); + /* biu_read_u8() */ + cpu_state.eaaddr = (BX + AL) & 0xffff; + tempb = readmemb((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + /* set_register8() */ + AL = tempb; + break; + + case 0xd8 ... 0xdf: /* ESC - FPU instructions. */ + /* read_operand16() */ + if (cpu_mod != 3) + do_cycles_i(2); /* load_operand() */ + tempw = cpu_state.pc; + geteaw(); + /* fpu_op() */ + if (hasfpu) { + if (fpu_softfloat) { + switch (opcode) { + case 0xd8: + ops_sf_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xd9: + ops_sf_fpu_8087_d9[rmdat & 0xff](rmdat); + break; + case 0xda: + ops_sf_fpu_8087_da[rmdat & 0xff](rmdat); + break; + case 0xdb: + ops_sf_fpu_8087_db[rmdat & 0xff](rmdat); + break; + case 0xdc: + ops_sf_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xdd: + ops_sf_fpu_8087_dd[rmdat & 0xff](rmdat); + break; + case 0xde: + ops_sf_fpu_8087_de[rmdat & 0xff](rmdat); + break; + case 0xdf: + ops_sf_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: + break; + } + } else { + switch (opcode) { + case 0xd8: + ops_fpu_8087_d8[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xd9: + ops_fpu_8087_d9[rmdat & 0xff](rmdat); + break; + case 0xdA: + ops_fpu_8087_da[rmdat & 0xff](rmdat); + break; + case 0xdb: + ops_fpu_8087_db[rmdat & 0xff](rmdat); + break; + case 0xdc: + ops_fpu_8087_dc[(rmdat >> 3) & 0x1f](rmdat); + break; + case 0xdd: + ops_fpu_8087_dd[rmdat & 0xff](rmdat); + break; + case 0xde: + ops_fpu_8087_de[rmdat & 0xff](rmdat); + break; + case 0xdf: + ops_fpu_8087_df[rmdat & 0xff](rmdat); + break; + + default: + break; + } + } + } + cpu_state.pc = tempw; /* Do this as the x87 code advances it, which is needed on + the 286+ core, but not here. */ + break; + + case 0xe0: /* LOOPNE & LOOPE */ + case 0xe1: + /* decrement_register16() */ + --CX; + do_cycles_i(2); + + zero_cond = !(cpu_state.flags & Z_FLAG); + if (opcode == 0xe1) + zero_cond = !zero_cond; + + /* read_operand8() */ + cpu_data = biu_pfq_fetchb(); + + if ((CX != 0x0000) && zero_cond) { + rel8 = (int8_t) cpu_data; + new_ip = (cpu_state.pc + rel8) & 0xffff; + reljmp(new_ip, 1); + jump = 1; + do_print = 0; + } else { + do_cycle_i(); + do_print = 1; + } + break; + + case 0xe2: /* LOOP */ + /* decrement_register16() */ + --CX; + do_cycles_i(2); + + /* read_operand8() */ + cpu_data = biu_pfq_fetchb(); + + if (CX != 0x0000) { + rel8 = (int8_t) cpu_data; + new_ip = (cpu_state.pc + rel8) & 0xffff; + reljmp(new_ip, 1); + jump = 1; + do_print = 0; + } + if (!jump) { + do_cycle(); + do_print = 1; + } + break; + + case 0xe3: /* JCXZ */ + do_cycles_i(2); + /* read_operand8() */ + cpu_data = biu_pfq_fetchb(); + + do_cycle_i(); + + if (CX == 0x0000) { + rel8 = (int8_t) cpu_data; + new_ip = (cpu_state.pc + rel8) & 0xffff; + reljmp(new_ip, 1); + jump = 1; + } else + do_cycle_i(); + break; + + case 0xe4: /* IN al, imm8 */ + bits = 8; + /* read_operand8() */ + cpu_data = biu_pfq_fetchb(); + do_cycles_i(2); + + /* biu_io_read_u8() */ + cpu_state.eaaddr = cpu_data; + cpu_io_vx0(bits, 0, cpu_state.eaaddr); + /* set_register8() */ + break; + + case 0xe5: /* IN ax, imm8 */ + bits = 16; + /* read_operand16() */ + cpu_data = biu_pfq_fetchb(); + do_cycles_i(2); + + /* biu_io_read_u16() */ + cpu_state.eaaddr = cpu_data; + cpu_io_vx0(bits, 0, cpu_state.eaaddr); + /* set_register16() */ + break; + + case 0xe6: /* OUT imm8, al */ + bits = 8; + /* read_operand8() */ + cpu_data = biu_pfq_fetchb(); + /* read_operand8() */ + tempb = AL; + do_cycles_i(2); + + /* biu_io_write_u8() */ + cpu_state.eaaddr = cpu_data; + cpu_data = tempb; + cpu_io_vx0(bits, 1, cpu_state.eaaddr); + break; + + case 0xe7: /* OUT imm8, ax */ + bits = 16; + /* read_operand8() */ + cpu_data = biu_pfq_fetchb(); + /* read_operand16() */ + tempw = AX; + do_cycles_i(2); + + /* biu_io_write_u16() */ + cpu_state.eaaddr = cpu_data; + cpu_data = tempw; + cpu_io_vx0(bits, 1, cpu_state.eaaddr); + break; + + case 0xe8: /* CALL rel16 */ + /* read_operand16() */ + rel16 = (int16_t) biu_pfq_fetchw(); + + biu_suspend_fetch(); + do_cycles_i(4); + + old_ip = cpu_state.pc; + new_ip = cpu_state.pc + rel16; + + set_ip(new_ip); + biu_queue_flush(); + do_cycles_i(3); + + push(&old_ip); + jump = 1; + break; + + case 0xe9: /* JMP rel16 */ + /* read_operand16() */ + rel16 = (int16_t) biu_pfq_fetchw(); + new_ip = (cpu_state.pc + rel16) & 0xffff; + + reljmp(new_ip, 1); + jump = 1; + break; + + case 0xea: /* JMP far [addr16:16] */ + /* read_operand_faraddr() */ + addr = biu_pfq_fetchw(); + tempw = biu_pfq_fetchw(); + load_cs(tempw); + set_ip(addr); + + biu_suspend_fetch(); + do_cycles_i(2); + biu_queue_flush(); + do_cycle_i(); + jump = 1; + break; + + case 0xeb: /* JMP rel8 */ + /* read_operand8() */ + rel8 = (int8_t) biu_pfq_fetchb(); + new_ip = (cpu_state.pc + rel8) & 0xffff; + + reljmp(new_ip, 1); + jump = 1; + break; + + case 0xec: /* IN al, dx */ + bits = 8; + /* read_operand8() */ + cpu_data = DX; + /* biu_io_read_u8() */ + cpu_state.eaaddr = cpu_data; + cpu_io_vx0(bits, 0, cpu_state.eaaddr); + /* set_register8() */ + break; + + case 0xed: /* IN ax, dx */ + bits = 16; + /* read_operand16() */ + cpu_data = DX; + /* biu_io_read_u16() */ + cpu_state.eaaddr = cpu_data; + cpu_io_vx0(bits, 0, cpu_state.eaaddr); + /* set_register16() */ + break; + + case 0xee: /* OUT dx, al */ + bits = 8; + /* read_operand8() */ + cpu_data = DX; + /* read_operand8() */ + tempb = AL; + do_cycle_i(); + + /* biu_io_write_u8() */ + cpu_state.eaaddr = cpu_data; + cpu_data = tempb; + cpu_io_vx0(bits, 1, cpu_state.eaaddr); + break; + + case 0xef: /* OUT dx, ax */ + bits = 16; + /* read_operand8() */ + cpu_data = DX; + /* read_operand16() */ + tempw = AX; + do_cycle_i(); + + /* biu_io_write_u16() */ + cpu_state.eaaddr = cpu_data; + cpu_data = tempw; + cpu_io_vx0(bits, 1, cpu_state.eaaddr); + break; + + case 0xf0: + case 0xf1: /* LOCK - F1 is alias */ + break; + + case 0xf2: /* REPNE */ + case 0xf3: /* REPE */ + break; + + case 0xf4: /* HLT */ + if (is_nec) + in_hlt = 1; + + if (!repeating) { + biu_suspend_fetch(); + // biu_queue_flush(); + do_cycles(2); + /* TODO: biu_halt(); */ + do_cycle(); + } + + do_cycle_i(); + do_cycle_i(); + do_cycle_i(); + if (irq_pending()) { + halted = 0; + check_interrupts(); + } else { + repeating = 1; + completed = 0; + + halted = 1; + } + + if (is_nec) + in_hlt = 0; + break; + + case 0xf5: /* CMC */ + cpu_state.flags ^= C_FLAG; + break; + + case 0xf6: /* Miscellaneuous Opcode Extensions, r/m8, imm8 */ + bits = 8; + if (cpu_mod != 3) + do_cycles_i(is_nec ? 1 : 2); /* load_operand() */ + negate = !!in_rep; + + if (is_nec && ((rmdat & 0x38) >= 0x20)) switch (rmdat & 0x38) { + case 0x20: /* MUL */ + /* read_operand8() */ + cpu_data = get_ea(); + + AX = AL * cpu_data; + if (AH) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + + do_cycles((cpu_mod == 3) ? 24 : 30); + break; + case 0x28: /* IMUL */ + /* read_operand8() */ + cpu_data = get_ea(); + + tempws = (int) ((int8_t) AL) * (int) ((int8_t) cpu_data); + AX = tempws & 0xffff; + if (((int16_t) AX >> 7) != 0 && ((int16_t) AX >> 7) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + + do_cycles((cpu_mod == 3) ? 13 : 19); + break; + case 0x30: /* DIV */ + /* read_operand8() */ + cpu_data = get_ea(); + + src16 = AX; + if (cpu_data) + tempw = src16 / cpu_data; + if (cpu_data && !(tempw & 0xff00)) { + AH = src16 % cpu_data; + AL = (src16 / cpu_data) & 0xff; + cpu_state.flags |= 0x8D5; + cpu_state.flags &= ~1; + } else { + intr_routine(0, 0); + break; + } + + do_cycles((cpu_mod == 3) ? 21 : 27); + break; + case 0x38: /* IDIV */ + /* read_operand8() */ + cpu_data = get_ea(); + + tempws = (int) (int16_t) AX; + if (cpu_data != 0) + tempws2 = tempws / (int) ((int8_t) cpu_data); + temps = tempws2 & 0xff; + if (cpu_data && ((int) temps == tempws2)) { + AH = (tempws % (int) ((int8_t) cpu_data)) & 0xff; + AL = tempws2 & 0xff; + cpu_state.flags |= 0x8D5; + cpu_state.flags &= ~1; + } else { + intr_routine(0, 0); + break; + } + + do_cycles((cpu_mod == 3) ? 11 : 17); + break; + } else switch (rmdat & 0x38) { + case 0x00: /* TEST */ + case 0x08: + /* read_operand8() */ + cpu_data = get_ea(); + /* read_operand8() */ + cpu_src = biu_pfq_fetch(); + + do_cycles_i(is_nec ? 1 : 2); + + /* math_op8() */ + test(bits, cpu_data, cpu_src); + break; + case 0x10: /* NOT */ + case 0x18: /* NEG */ + /* read_operand8() */ + cpu_data = get_ea(); + /* math_op8() */ + if ((rmdat & 0x38) == 0x10) + cpu_data = ~cpu_data; + else { + cpu_src = cpu_data; + cpu_dest = 0; + sub(bits); + } + + if (cpu_mod != 3) + do_cycles_i(2); + + /* write_operand8() */ + set_ea(cpu_data); + break; + + case 0x20: /* MUL */ + case 0x28: /* IMUL */ + /* read_operand8() */ + cpu_data = get_ea(); + + /* mul8() */ + old_flags = cpu_state.flags; + mul(get_accum(bits), cpu_data); + prod16 = ((cpu_dest & 0xff) << 8) | (cpu_data & 0xff); + if (negate) + prod16 = -prod16; + cpu_dest = prod16 >> 8; + cpu_data = prod16 & 0xff; + AL = (uint8_t) cpu_data; + AH = (uint8_t) cpu_dest; + set_co_mul(bits, AH != ((AL & 0x80) == 0 || + (rmdat & 0x38) == 0x20 ? 0 : 0xff)); + if (!is_nec) + cpu_data = AH; + set_sf(bits); + set_pf(); + /* NOTE: When implementing the V20, care should be taken to not change + the zero flag. */ + if (is_nec) + cpu_state.flags = (cpu_state.flags & ~Z_FLAG) | (old_flags & Z_FLAG); + break; + + case 0x30: /* DIV */ + case 0x38: /* IDIV */ + /* read_operand8() */ + cpu_data = get_ea(); + + cpu_src = cpu_data; + if (x86_div(AL, AH)) { + if (!is_nec && negate) + AL = -AL; + do_cycle(); + } + break; + } + break; + + case 0xf7: /* Miscellaneuous Opcode Extensions, r/m16, imm16 */ + bits = 16; + if (cpu_mod != 3) + do_cycles_i(is_nec ? 1 : 2); /* load_operand() */ + negate = !!in_rep; + + if (is_nec && ((rmdat & 0x38) >= 0x20)) switch (rmdat & 0x38) { + case 0x20: /* MUL */ + /* read_operand16() */ + cpu_data = get_ea(); + + templ = AX * cpu_data; + AX = templ & 0xFFFF; + DX = templ >> 16; + if (DX) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + + do_cycles((cpu_mod == 3) ? 29 : 35); + break; + case 0x28: /* IMUL */ + /* read_operand16() */ + cpu_data = get_ea(); + + templ = (int) ((int16_t) AX) * (int) ((int16_t) cpu_data); + AX = templ & 0xFFFF; + DX = templ >> 16; + if (((int32_t) templ >> 15) != 0 && ((int32_t) templ >> 15) != -1) + cpu_state.flags |= (C_FLAG | V_FLAG); + else + cpu_state.flags &= ~(C_FLAG | V_FLAG); + + do_cycles((cpu_mod == 3) ? 17 : 27); + break; + case 0x30: /* DIV */ + /* read_operand16() */ + cpu_data = get_ea(); + + templ = (DX << 16) | AX; + if (cpu_data) + templ2 = templ / cpu_data; + if (cpu_data && !(templ2 & 0xffff0000)) { + DX = templ % cpu_data; + AX = (templ / cpu_data) & 0xffff; + cpu_data = AX; + set_pzs(16); + } else { + intr_routine(0, 0); + break; + } + + do_cycles((cpu_mod == 3) ? 26 : 36); + break; + case 0x38: /* IDIV */ + /* read_operand16() */ + cpu_data = get_ea(); + + tempws = (int) ((DX << 16) | AX); + if (cpu_data) + tempws2 = tempws / (int) ((int16_t) cpu_data); + temps16 = tempws2 & 0xffff; + if ((cpu_data != 0) && ((int) temps16 == tempws2)) { + DX = tempws % (int) ((int16_t) cpu_data); + AX = tempws2 & 0xffff; + cpu_data = AX; + set_pzs(16); + } else { + intr_routine(0, 0); + break; + } + + do_cycles((cpu_mod == 3) ? 13 : 23); + break; + } else switch (rmdat & 0x38) { + case 0x00: /* TEST */ + case 0x08: + /* read_operand16() */ + cpu_data = get_ea(); + /* read_operand16() */ + cpu_src = biu_pfq_fetch(); + + do_cycle_i(); + + /* math_op16() */ + test(bits, cpu_data, cpu_src); + break; + case 0x10: /* NOT */ + case 0x18: /* NEG */ + /* read_operand16() */ + cpu_data = get_ea(); + /* math_op16() */ + if ((rmdat & 0x38) == 0x10) + cpu_data = ~cpu_data; + else { + cpu_src = cpu_data; + cpu_dest = 0; + sub(bits); + } + + if (cpu_mod != 3) + do_cycles_i(2); + + /* write_operand16() */ + set_ea(cpu_data); + break; + + case 0x20: /* MUL */ + case 0x28: /* IMUL */ + /* read_operand16() */ + cpu_data = get_ea(); + + /* mul8() */ + old_flags = cpu_state.flags; + mul(get_accum(bits), cpu_data); + prod32 = (((uint32_t) cpu_dest) << 16) | cpu_data; + if (negate) + prod32 = -prod32; + cpu_dest = prod32 >> 16; + cpu_data = prod32 & 0xffff; + AX = cpu_data; + DX = cpu_dest; + set_co_mul(bits, DX != ((AX & 0x8000) == 0 || + (rmdat & 0x38) == 0x20 ? 0 : 0xffff)); + cpu_data = DX; + set_sf(bits); + set_pf(); + /* NOTE: When implementing the V20, care should be taken to not change + the zero flag. */ + if (is_nec) + cpu_state.flags = (cpu_state.flags & ~Z_FLAG) | (old_flags & Z_FLAG); + break; + + case 0x30: /* DIV */ + case 0x38: /* IDIV */ + /* read_operand16() */ + cpu_data = get_ea(); + + cpu_src = cpu_data; + if (x86_div(AX, DX)) { + if (!is_nec && negate) + AX = -AX; + do_cycle(); + } + break; + } + break; + + case 0xf8: /* CLCSTC */ + case 0xf9: + set_cf(opcode & 1); + break; + + case 0xfa: /* CLISTI */ + case 0xfb: + set_if(opcode & 1); + break; + + case 0xfc: /* CLDSTD */ + case 0xfd: + set_df(opcode & 1); + break; + + case 0xfe: + bits = 8; + if (cpu_mod != 3) + do_cycles_i(is_nec ? 1 : 2); /* load_operand() */ + read_ea(((rmdat & 0x38) == 0x18) || ((rmdat & 0x38) == 0x28), bits); + switch (rmdat & 0x38) { + case 0x00: /* INC rm */ + case 0x08: /* DEC rm */ + /* read_operand8() */ + /* math_op8() */ + cpu_dest = cpu_data; + cpu_src = 1; + if ((rmdat & 0x38) == 0x00) { + cpu_data = cpu_dest + cpu_src; + set_of_add(bits); + } else { + cpu_data = cpu_dest - cpu_src; + set_of_sub(bits); + } + do_af(); + set_pzs(bits); + + if (cpu_mod != 3) + do_cycles_i(2); + /* write_operand8() */ + set_ea(cpu_data); + break; + case 0x10: /* CALL rm */ + /* read_operand8() */ + cpu_data_opff_rm(); + + cpu_state.oldpc = cpu_state.pc; + push((uint16_t *) &(cpu_state.oldpc)); + + biu_suspend_fetch(); + do_cycles(4); + biu_queue_flush(); + + set_ip(cpu_data | 0xff00); + break; + case 0x18: /* CALL rmd */ + if (cpu_mod == 3) { + /* biu_read_u8() */ + cpu_state.eaaddr = 0x0004; + tempb = readmemb((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + + old_cs = CS & 0x00ff; + push(&old_cs); + old_ip = cpu_state.pc & 0x00ff; + push(&old_ip); + + biu_suspend_fetch(); + do_cycles(4); + biu_queue_flush(); + + read_ea_8to16(); + set_ip(cpu_data); + } else { + /* read_operand8() */ + new_ip = cpu_data | 0xff00; + + do_cycles_i(3); + + /* biu_read_u8() */ + read_ea2(bits); + cpu_data |= 0xff00; + new_cs = cpu_data; + + do_cycle_i(); + biu_suspend_fetch(); + do_cycles_i(3); + + old_cs = CS & 0x00ff; + push(&old_cs); + old_ip = cpu_state.pc & 0x00ff; + + load_cs(new_cs); + set_ip(new_ip); + + do_cycles_i(3); + biu_queue_flush(); + do_cycles_i(3); + + push(&old_ip); + } + break; + case 0x20: /* JMP rm */ + /* read_operand8() */ + cpu_data_opff_rm(); + + set_ip(cpu_data | 0xff00); + + biu_suspend_fetch(); + do_cycles(4); + biu_queue_flush(); + break; + case 0x28: /* JMP rmd */ + if (cpu_mod == 3) { + /* biu_read_u8() */ + cpu_state.eaaddr = 0x0004; + tempb = readmemb((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + + biu_suspend_fetch(); + do_cycles(4); + biu_queue_flush(); + + read_ea_8to16(); + set_ip(cpu_data); + } else { + /* read_operand8() */ + new_ip = cpu_data | 0xff00; + + /* biu_read_u8() */ + read_ea2(bits); + cpu_data |= 0xff00; + new_cs = cpu_data; + + biu_suspend_fetch(); + do_cycles(4); + biu_queue_flush(); + + load_cs(new_cs); + set_ip(new_ip); + } + break; + case 0x30: /* PUSH rm */ + case 0x38: + /* read_operand8() */ + do_cycles_i(3); + cpu_data &= 0x00ff; + push((uint16_t *) &cpu_data); + break; + } + break; + + case 0xff: + bits = 16; + if (cpu_mod != 3) + do_cycles_i(is_nec ? 1 : 2); /* load_operand() */ + read_ea(((rmdat & 0x38) == 0x18) || ((rmdat & 0x38) == 0x28), bits); + switch (rmdat & 0x38) { + case 0x00: /* INC rm */ + case 0x08: /* DEC rm */ + /* read_operand16() */ + /* math_op16() */ + cpu_dest = cpu_data; + cpu_src = 1; + if ((rmdat & 0x38) == 0x00) { + cpu_data = cpu_dest + cpu_src; + set_of_add(bits); + } else { + cpu_data = cpu_dest - cpu_src; + set_of_sub(bits); + } + do_af(); + set_pzs(bits); + if (cpu_mod != 3) + do_cycles_i(2); + /* write_operand16() */ + set_ea(cpu_data); + break; + case 0x10: /* CALL rm */ + /* read_operand16() */ + cpu_data_opff_rm(); + + biu_suspend_fetch(); + do_cycles(4); + + cpu_state.oldpc = cpu_state.pc; + + old_ip = cpu_state.pc; + set_ip(cpu_data); + biu_queue_flush(); + do_cycles_i(3); + + push(&old_ip); + break; + case 0x18: /* CALL rmd */ + if (cpu_mod == 3) { + new_ip = cpu_data; + + /* biu_read_u16() */ + cpu_state.eaaddr = 0x0004; + new_cs = readmemw((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + + do_cycle_i(); + biu_suspend_fetch(); + do_cycles_i(3); + + push(&CS); + old_ip = cpu_state.pc; + set_ip(new_ip); + + load_cs(new_cs); + + do_cycles_i(3); + biu_queue_flush(); + do_cycles_i(3); + + push(&old_ip); + } else { + do_cycle_i(); + /* read_operand_farptr() */ + new_ip = cpu_data; + read_ea2(bits); + new_cs = cpu_data; + + do_cycle_i(); + + biu_suspend_fetch(); + do_cycles_i(3); + + push(&CS); + + load_cs(new_cs); + old_ip = cpu_state.pc; + set_ip(new_ip); + do_cycles_i(3); + biu_queue_flush(); + do_cycles_i(3); + push(&old_ip); + } + break; + case 0x20: /* JMP rm */ + /* read_operand16() */ + cpu_data_opff_rm(); + + biu_suspend_fetch(); + do_cycle_i(); + set_ip(cpu_data); + biu_queue_flush(); + break; + case 0x28: /* JMP rmd */ + if (cpu_mod == 3) { + new_ip = cpu_data; + + do_cycle(); + biu_suspend_fetch(); + do_cycle(); + + /* biu_read_u16() */ + cpu_state.eaaddr = 0x0004; + new_cs = readmemw((ovr_seg ? *ovr_seg : ds), cpu_state.eaaddr); + + push(&CS); + biu_queue_flush(); + } else { + do_cycle_i(); + biu_suspend_fetch(); + do_cycle_i(); + + /* read_operand_farptr() */ + new_ip = cpu_data; + read_ea2(bits); + new_cs = cpu_data; + + load_cs(new_cs); + set_ip(new_ip); + biu_queue_flush(); + } + break; + case 0x30: /* PUSH rm */ + case 0x38: + /* read_operand16() */ + do_cycles_i(3); + + if (cpu_rm == 4) + cpu_rm -= 2; + push((uint16_t *) &cpu_data); + break; + } + break; + + default: + x808x_log("Illegal opcode: %02X\n", opcode); + biu_pfq_fetchb(); + do_cycles(8); + break; + } +} + +/* Executes instructions up to the specified number of cycles. */ +void +execvx0(int cycs) +{ + cycles += cycs; + + while (cycles > 0) { + if (started) { + started = 0; + startx86(); + } + + if (!repeating) { + cpu_state.oldpc = cpu_state.pc; + + if (clear_lock) { + in_lock = 0; + clear_lock = 0; + } + + if (!is_nec || (cpu_state.flags & MD_FLAG)) + decode(); + + oldc = cpu_state.flags & C_FLAG; + } + + x808x_log("[%04X:%04X] Opcode: %02X\n", CS, cpu_state.pc, opcode); + + execute_instruction(); + + if (completed) { + if (opcode != 0xf4) + finalize(); + + check_interrupts(); + + if (noint) + noint = 0; + } + +#ifdef USE_GDBSTUB + if (gdbstub_instruction()) + return; +#endif + } +} diff --git a/src/cpu/vx0_biu.c b/src/cpu/vx0_biu.c new file mode 100644 index 0000000000..b52b142458 --- /dev/null +++ b/src/cpu/vx0_biu.c @@ -0,0 +1,1152 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 808x BIU emulation. + * + * Authors: Andrew Jenner, + * Miran Grca, + * + * Copyright 2015-2020 Andrew Jenner. + * Copyright 2016-2020 Miran Grca. + */ +#include +#include +#include +#include +#include +#include + +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include "x86.h" +#include <86box/machine.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/ppi.h> +#include <86box/timer.h> +#include <86box/gdbstub.h> +#include <86box/plat_fallthrough.h> +#include <86box/plat_unused.h> +#include "vx0_biu.h" + +#define do_cycle() wait(1) +#define do_cycle_i() do_cycle() + +uint8_t biu_preload_byte = 0x00; + +int bus_request_type = 0; + +int pic_data = -1; +int biu_queue_preload = 0; + +/* The IP equivalent of the current prefetch queue position. */ +static uint16_t pfq_ip = 0x0000; +static uint16_t pfq_in = 0x0000; + +/* Variables to aid with the prefetch queue operation. */ +static int pfq_size = 0; + +static int cycles_ex = 0; + +/* The prefetch queue (4 bytes for 8088, 6 bytes for 8086). */ +static uint8_t pfq[6]; + +static int biu_cycles = 0; +static int biu_wait = 0; +static int biu_wait_length = 0; +static int refresh = 0; +static uint16_t mem_data = 0; +static uint32_t mem_seg = 0; +static uint16_t mem_addr = 0; +static int biu_state = 0; +static int biu_next_state = 0; +static int biu_scheduled_state = 0; +static int biu_state_length = 0; +static int biu_state_total_len = 0; +static int dma_state = 0; +static int dma_state_length = 0; +static int wait_states = 0; +static int fetch_suspended = 0; +static int ready = 1; +static int dma_wait_states = 0; + +#define BUS_CYCLE (biu_cycles & 3) +#define BUS_CYCLE_T1 biu_cycles = 0 +#define BUS_CYCLE_NEXT biu_cycles = (biu_cycles + 1) & 3 + +/* DEBUG stuff. */ +const char *lpBiuStates[7] = { "Ti ", "Ti S ", "Ti D ", "Ti R ", "Tw ", "T%i PF", "T%i EU" }; + +#ifdef ENABLE_808X_BIU_LOG +int x808x_biu_do_log = ENABLE_808X_BIU_LOG; + +static void +x808x_biu_log(const char *fmt, ...) +{ + va_list ap; + + if (x808x_biu_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define x808x_biu_log(fmt, ...) +#endif + +void +biu_set_bus_cycle(int bus_cycle) +{ + biu_cycles = bus_cycle; +} + +void +biu_set_bus_state(int bus_state) +{ + biu_state = bus_state; +} + +void +biu_set_bus_next_state(int bus_next_state) +{ + biu_state = bus_next_state; +} + +void +biu_set_cycle_t1(void) +{ + BUS_CYCLE_T1; +} + +void +biu_set_next_cycle(void) +{ + BUS_CYCLE_NEXT; +} + +int +biu_get_bus_cycle(void) +{ + return BUS_CYCLE; +} + +int +biu_get_bus_state(void) +{ + return biu_state; +} + +int +biu_get_bus_next_state(void) +{ + return biu_next_state; +} + +static void pfq_add(void); + +static void +pfq_resume(int delay) +{ + if (is_nec) + biu_state = BIU_STATE_PF; + else { + biu_state = BIU_STATE_RESUME; + biu_state_length = delay; + biu_state_total_len = delay; + } +} + +static void +pfq_switch_to_pf(int delay) +{ + if (is_nec) + biu_next_state = BIU_STATE_PF; + else { + biu_next_state = BIU_STATE_RESUME; + biu_state_length = delay; + biu_state_total_len = delay; + } +} + +static uint8_t +biu_queue_delay(void) +{ + if (is8086) + return pfq_pos == 4; + else + return pfq_pos == 3; +} + +static void +pfq_schedule(void) +{ + if (biu_state == BIU_STATE_EU) { + if (!is_nec && biu_queue_delay()) { + biu_next_state = BIU_STATE_DELAY; + biu_state_length = 3; + biu_state_total_len = 3; + } else if ((is_nec || !fetch_suspended) && (pfq_pos < 4)) + biu_next_state = BIU_STATE_PF; + else + biu_next_state = BIU_STATE_IDLE; + } else { + if (!is_nec && biu_queue_delay()) { + biu_next_state = BIU_STATE_DELAY; + biu_state_length = 3; + biu_state_total_len = 3; + } else + biu_next_state = BIU_STATE_PF; + } +} + +void +biu_reset(void) +{ + BUS_CYCLE_T1; + biu_cycles = 0; + biu_wait = 0; + refresh = 0; + bus_request_type = 0; + biu_queue_preload = 0; + pic_data = -1; + mem_data = 0; + mem_seg = 0; + mem_addr = 0; + wait_states = 0; + dma_state = DMA_STATE_IDLE; + dma_state_length = 0; + biu_state = BIU_STATE_IDLE; + biu_next_state = BIU_STATE_IDLE; + biu_scheduled_state = BIU_STATE_IDLE; + biu_state_length = 0; + pfq_size = is8086 ? 6 : 4; + pfq_in = 0x0000; +} + +static void +process_timers(void) +{ + /* On 808x systems, clock speed is usually crystal frequency divided by an integer. */ + tsc += ((uint64_t) xt_cpu_multi >> 32ULL); /* Shift xt_cpu_multi by 32 bits to + the right and then multiply. */ + if (TIMER_VAL_LESS_THAN_VAL(timer_target, (uint64_t) tsc)) + timer_process(); +} + +static void +cycles_forward(int c) +{ + for (int i = 0; i < c; i++) { + cycles--; + if (!is286) + process_timers(); + } + + cycles_ex++; +} + +static void +bus_outb(uint16_t port, uint8_t val) +{ + outb(port, val); +} + +static void +bus_outw(uint16_t port, uint16_t val) +{ + outw(port, val); +} + +static uint8_t +bus_inb(uint16_t port) +{ + uint8_t ret; + + ret = inb(port); + + return ret; +} + +static uint16_t +bus_inw(uint16_t port) +{ + uint16_t ret; + + ret = inw(port); + + return ret; +} + +static void +bus_do_io(int io_type) +{ + int old_cycles = cycles; + + x808x_biu_log("(%02X) bus_do_io(%02X): %04X\n", opcode, io_type, cpu_state.eaaddr); + + if (io_type & BUS_OUT) { + if (io_type & BUS_WIDE) + bus_outw((uint16_t) cpu_state.eaaddr, AX); + else if (io_type & BUS_HIGH) + bus_outb(((uint16_t) cpu_state.eaaddr + 1) & 0xffff, AH); + else + bus_outb((uint16_t) cpu_state.eaaddr, AL); + } else { + if (io_type & BUS_WIDE) + AX = bus_inw((uint16_t) cpu_state.eaaddr); + else if (io_type & BUS_HIGH) + AH = bus_inb(((uint16_t) cpu_state.eaaddr + 1) & 0xffff); + else + AL = bus_inb((uint16_t) cpu_state.eaaddr); + } + + resub_cycles(old_cycles); +} + +static void +bus_writeb(uint32_t seg, uint32_t addr, uint8_t val) +{ + write_mem_b(seg + addr, val); +} + +static void +bus_writew(uint32_t seg, uint32_t addr, uint16_t val) +{ + write_mem_w(seg + addr, val); +} + +static uint8_t +bus_readb(uint32_t seg, uint32_t addr) +{ + uint8_t ret = read_mem_b(seg + addr); + + return ret; +} + +static uint16_t +bus_readw(uint32_t seg, uint32_t addr) +{ + uint16_t ret = read_mem_w(seg + addr); + + return ret; +} + +static void +bus_do_mem(int io_type) +{ + int old_cycles = cycles; + + if (io_type & BUS_OUT) { + if (io_type & BUS_WIDE) + bus_writew(mem_seg, (uint32_t) mem_addr, mem_data); + else if (io_type & BUS_HIGH) { + if (is186 && !is_nec) + bus_writeb(mem_seg, ((uint32_t) mem_addr) + 1, mem_data >> 8); + else + bus_writeb(mem_seg, (uint32_t) ((mem_addr + 1) & 0xffff), mem_data >> 8); + } else + bus_writeb(mem_seg, (uint32_t) mem_addr, mem_data & 0xff); + } else { + if (io_type & BUS_WIDE) + mem_data = bus_readw(mem_seg, (uint32_t) mem_addr); + else if (io_type & BUS_HIGH) { + if (is186 && !is_nec) + mem_data = (mem_data & 0x00ff) | + (((uint16_t) bus_readb(mem_seg, ((uint32_t) mem_addr) + 1)) << 8); + else + mem_data = (mem_data & 0x00ff) | + (((uint16_t) bus_readb(mem_seg, (uint32_t) ((mem_addr + 1) & 0xffff))) << 8); + } else + mem_data = (mem_data & 0xff00) | ((uint16_t) bus_readb(mem_seg, (uint32_t) mem_addr)); + } + + resub_cycles(old_cycles); +} + +static void +biu_print_cycle(void) +{ + if ((CS == DEBUG_SEG) && (cpu_state.pc >= DEBUG_OFF_L) && (cpu_state.pc <= DEBUG_OFF_H)) { + if (biu_state >= BIU_STATE_PF) { + if (biu_wait) { + x808x_biu_log("[%04X:%04X] [%i, %i] (%i) %s (%i)\n", CS, cpu_state.pc, dma_state, dma_wait_states, + pfq_pos, lpBiuStates[BIU_STATE_WAIT], wait_states); + } else { + char temp[16] = { 0 }; + + sprintf(temp, lpBiuStates[biu_state], biu_cycles + 1); + x808x_biu_log("[%04X:%04X] [%i, %i] (%i) %s\n", CS, cpu_state.pc, dma_state, dma_wait_states, + pfq_pos, temp); + } + } else { + x808x_biu_log("[%04X:%04X] [%i, %i] (%i) %s\n", CS, cpu_state.pc, dma_state, dma_wait_states, + pfq_pos, lpBiuStates[biu_state]); + } + } +} + +static void +do_wait(void) +{ + if (wait_states > 0) + wait_states--; + + if (dma_wait_states > 0) + dma_wait_states--; +} + +static void +run_dma_cycle(void) +{ + int bus_cycle_check = ((biu_state < BIU_STATE_PF) || (BUS_CYCLE == BUS_T3) || + (BUS_CYCLE == BUS_T4) || biu_wait) && !in_lock; + + switch (dma_state) { + case DMA_STATE_TIMER: + dma_state = DMA_STATE_DREQ; + dma_state_length = 1; + break; + case DMA_STATE_DREQ: + dma_state = DMA_STATE_HRQ; + dma_state_length = 1; + break; + case DMA_STATE_HRQ: + if (!in_lock && bus_cycle_check) { + dma_state = DMA_STATE_HLDA; + dma_state_length = 1; + } + break; + case DMA_STATE_HLDA: + dma_state = DMA_STATE_OPERATING; + dma_state_length = 4; + break; + case DMA_STATE_OPERATING: + dma_state_length--; + if (dma_state_length == 3) { + dma_wait_states = 7; + ready = 0; + } else if (dma_state_length == 0) { + dma_state = DMA_STATE_IDLE; + dma_state_length = 1; + } + break; + } +} + +static void +biu_cycle_idle(int type) +{ + if ((CS == DEBUG_SEG) && (cpu_state.pc >= DEBUG_OFF_L) && (cpu_state.pc <= DEBUG_OFF_H)) { + x808x_biu_log("[%04X:%04X] [%i, %i] (%i) %s\n", CS, cpu_state.pc, dma_state, dma_wait_states, + pfq_pos, lpBiuStates[type]); + } + + run_dma_cycle(); + cycles_forward(1); + + do_wait(); +} + +/* Reads a byte from the memory but does not advance the BIU. */ +static uint8_t +readmembf(uint32_t a) +{ + uint8_t ret; + + a = cs + (a & 0xffff); + ret = read_mem_b(a); + + return ret; +} + +static uint16_t +readmemwf(uint16_t a) +{ + uint16_t ret; + + ret = read_mem_w(cs + (a & 0xffff)); + + return ret; +} + +static void +do_bus_access(void) +{ + int io_type = (biu_state == BIU_STATE_EU) ? bus_request_type : BUS_CODE; + + x808x_biu_log("[%04X:%04X] %02X bus access %02X\n", CS, cpu_state.pc, opcode, io_type); + + if (io_type != 0) { + wait_states = 0; + switch (io_type & BUS_ACCESS_TYPE) { + case BUS_CODE: + if (is8086) + pfq_in = readmemwf(pfq_ip); + else + pfq_in = readmembf(pfq_ip); + break; + case BUS_IO: + bus_do_io(io_type); + break; + case BUS_MEM: + bus_do_mem(io_type); + break; + case BUS_PIC: + pic_data = pic_irq_ack(); + break; + default: + break; + } + } +} + +void +resub_cycles(int old_cycles) +{ + if (old_cycles > cycles) + wait_states = old_cycles - cycles; + + cycles = old_cycles; +} + +static uint8_t +biu_queue_has_room(void) +{ + if (is8086) + return pfq_pos < 5; + else + return pfq_pos < 4; +} + +static int bus_access_done = 0; + +static void +biu_do_cycle(void) +{ + int biu_old_state = biu_state; + + biu_print_cycle(); + + switch (biu_state) { + default: + fatal("Invalid BIU state: %02X\n", biu_state); + break; + case BIU_STATE_RESUME: + if (biu_state_length > 0) { + biu_state_length--; + if (biu_state_length == 0) { + biu_state = BIU_STATE_PF; + biu_next_state = BIU_STATE_PF; + } + } else { + biu_state = BIU_STATE_PF; + biu_next_state = BIU_STATE_PF; + } + break; + case BIU_STATE_IDLE: + case BIU_STATE_SUSP: + biu_state = biu_next_state; + break; + case BIU_STATE_DELAY: + if (biu_state_length > 0) { + biu_state_length--; + if (biu_state_length == 0) { + if (biu_queue_has_room()) { + biu_state = BIU_STATE_PF; + biu_next_state = BIU_STATE_PF; + } else { + biu_state = BIU_STATE_IDLE; + biu_next_state = BIU_STATE_IDLE; + } + } + } else { + if (biu_queue_has_room()) { + biu_state = BIU_STATE_PF; + biu_next_state = BIU_STATE_PF; + } else { + biu_state = BIU_STATE_IDLE; + biu_next_state = BIU_STATE_IDLE; + } + } + break; + case BIU_STATE_PF: + case BIU_STATE_EU: + if (biu_wait) { + if ((wait_states == 0) && (dma_wait_states == 0)) { + biu_wait = 0; + BUS_CYCLE_NEXT; + } + } else { + if (BUS_CYCLE == BUS_T4) { + if (biu_state == BIU_STATE_PF) + pfq_add(); + biu_state = biu_next_state; + } + + if ((BUS_CYCLE == BUS_T3) && (biu_state == BIU_STATE_EU)) { + if ((bus_request_type != 0) && ((bus_request_type & BUS_ACCESS_TYPE) == BUS_IO)) + wait_states++; + } + + if ((BUS_CYCLE == BUS_T3) && ((wait_states != 0) || (dma_wait_states != 0))) + biu_wait = 1; + else { + biu_wait = 0; + BUS_CYCLE_NEXT; + } + + if ((BUS_CYCLE == BUS_T1) && (biu_state == BIU_STATE_IDLE) && biu_queue_delay()) { + if (biu_old_state == BIU_STATE_EU) + pfq_resume(2); + else + biu_state = BIU_STATE_PF; + } + } + + if (bus_access_done && !biu_wait) + bus_access_done = 0; + break; + } +} + +static int +biu_is_last_tw(void) +{ + return ((biu_state >= BIU_STATE_PF) && biu_wait && ((wait_states + dma_wait_states) == 1)); +} + +static void +biu_cycle(void) +{ + if (biu_state >= BIU_STATE_PF) { + if (BUS_CYCLE == BUS_T2) + pfq_schedule(); + else if (((BUS_CYCLE == BUS_T3) && !biu_wait) || biu_is_last_tw()) { + if (!bus_access_done) { + do_bus_access(); + bus_access_done = 1; + } + } + } + + run_dma_cycle(); + + biu_do_cycle(); + + cycles_forward(1); + + do_wait(); +} + +static void +biu_eu_request(void) +{ + switch (biu_state) { + default: + fatal("Invalid BIU state: %02X\n", biu_state); + break; + case BIU_STATE_RESUME: + /* Resume it - leftover cycles. */ + if (!is_nec) for (uint8_t i = 0; i < (biu_state_total_len - biu_state_length); i++) + biu_cycle_idle(biu_state); + break; + case BIU_STATE_IDLE: + case BIU_STATE_SUSP: + /* Resume it - 3 cycles. */ + if (!is_nec) for (uint8_t i = 0; i < 3; i++) + biu_cycle_idle(biu_state); + break; + case BIU_STATE_DELAY: + case BIU_STATE_EU: + /* Do the request immediately (needs hardware testing). */ + biu_state_length = 0; + break; + case BIU_STATE_PF: + /* Transition the state. */ + switch (BUS_CYCLE) { + case BUS_T1: + case BUS_T2: + /* Leftover BIU cycles. */ + do + biu_cycle(); + while (BUS_CYCLE != BUS_T1); + break; + case BUS_T3: + case BUS_T4: + /* Leftover BIU cycles. */ + do + biu_cycle(); + while (BUS_CYCLE != BUS_T1); + /* The two abort cycles. */ + if (!is_nec) for (uint8_t i = 0; i < 2; i++) + biu_cycle_idle(BIU_STATE_IDLE); + break; + + default: + break; + } + break; + } + + biu_state = BIU_STATE_EU; + biu_next_state = BIU_STATE_EU; + + biu_state_length = 0; +} + +void +wait(int c) +{ + x808x_biu_log("[%04X:%04X] %02X %i cycles\n", CS, cpu_state.pc, opcode, c); + + for (uint8_t i = 0; i < c; i++) + biu_cycle(); +} + +/* This is for external subtraction of cycles, ie. wait states. */ +void +sub_cycles(int c) +{ + cycles -= c; +} + +void +biu_begin_eu(void) +{ + biu_eu_request(); +} + +static void +biu_wait_for_write_finish(void) +{ + while (BUS_CYCLE != BUS_T4) { + biu_cycle(); + if (biu_wait_length == 1) + break; + } +} + +void +biu_wait_for_read_finish(void) +{ + biu_wait_for_write_finish(); + biu_cycle(); +} + +void +cpu_io_vx0(int bits, int out, uint16_t port) +{ + /* Do this, otherwise, the first half of the operation never happens. */ + if ((BUS_CYCLE == BUS_T4) && (biu_state == BIU_STATE_EU)) + BUS_CYCLE_T1; + + if (out) { + if (bits == 16) { + if (is8086 && !(port & 1)) { + bus_request_type = BUS_IO | BUS_OUT | BUS_WIDE; + biu_begin_eu(); + biu_wait_for_write_finish(); + } else { + bus_request_type = BUS_IO | BUS_OUT; + biu_begin_eu(); + biu_wait_for_write_finish(); + biu_cycle(); + biu_state = BIU_STATE_EU; + biu_state_length = 0; + bus_request_type = BUS_IO | BUS_OUT | BUS_HIGH; + biu_wait_for_write_finish(); + } + } else { + bus_request_type = BUS_IO | BUS_OUT; + biu_begin_eu(); + biu_wait_for_write_finish(); + } + } else { + if (bits == 16) { + if (is8086 && !(port & 1)) { + bus_request_type = BUS_IO | BUS_WIDE; + biu_begin_eu(); + biu_wait_for_read_finish(); + } else { + bus_request_type = BUS_IO; + biu_begin_eu(); + biu_wait_for_read_finish(); + biu_state = BIU_STATE_EU; + biu_state_length = 0; + bus_request_type = BUS_IO | BUS_HIGH; + biu_wait_for_read_finish(); + } + } else { + bus_request_type = BUS_IO; + biu_begin_eu(); + biu_wait_for_read_finish(); + } + } + + bus_request_type = 0; +} + +void +biu_state_set_eu(void) +{ + biu_state = BIU_STATE_EU; + biu_state_length = 0; +} + +/* Reads a byte from the memory and advances the BIU. */ +uint8_t +readmemb_vx0(uint32_t s, uint16_t a) +{ + uint8_t ret; + + mem_seg = s; + mem_addr = a; + /* Do this, otherwise, the first half of the operation never happens. */ + if ((BUS_CYCLE == BUS_T4) && (biu_state == BIU_STATE_EU)) + BUS_CYCLE_T1; + bus_request_type = BUS_MEM; + biu_begin_eu(); + biu_wait_for_read_finish(); + ret = mem_data & 0xff; + bus_request_type = 0; + + return ret; +} + +/* Reads a word from the memory and advances the BIU. */ +uint16_t +readmemw_vx0(uint32_t s, uint16_t a) +{ + uint16_t ret; + + mem_seg = s; + mem_addr = a; + /* Do this, otherwise, the first half of the operation never happens. */ + if ((BUS_CYCLE == BUS_T4) && (biu_state == BIU_STATE_EU)) + BUS_CYCLE_T1; + if (is8086 && !(a & 1)) { + bus_request_type = BUS_MEM | BUS_WIDE; + biu_begin_eu(); + biu_wait_for_read_finish(); + } else { + bus_request_type = BUS_MEM | BUS_HIGH; + biu_begin_eu(); + biu_wait_for_read_finish(); + biu_state = BIU_STATE_EU; + biu_state_length = 0; + bus_request_type = BUS_MEM; + biu_wait_for_read_finish(); + } + ret = mem_data; + bus_request_type = 0; + + return ret; +} + +uint16_t +readmem_vx0(uint32_t s) +{ + if (opcode & 1) + return readmemw_vx0(s, cpu_state.eaaddr); + else + return (uint16_t) readmemb_vx0(s, cpu_state.eaaddr); +} + +uint32_t +readmeml_vx0(uint32_t s, uint16_t a) +{ + uint32_t temp; + + temp = (uint32_t) (readmemw_vx0(s, a + 2)) << 16; + temp |= readmemw_vx0(s, a); + + return temp; +} + +uint64_t +readmemq_vx0(uint32_t s, uint16_t a) +{ + uint64_t temp; + + temp = (uint64_t) (readmeml_vx0(s, a + 4)) << 32; + temp |= readmeml_vx0(s, a); + + return temp; +} + +/* Writes a byte to the memory and advances the BIU. */ +void +writememb_vx0(uint32_t s, uint32_t a, uint8_t v) +{ + uint32_t addr = s + a; + + mem_seg = s; + mem_addr = a; + mem_data = v; + /* Do this, otherwise, the first half of the operation never happens. */ + if ((BUS_CYCLE == BUS_T4) && (biu_state == BIU_STATE_EU)) + BUS_CYCLE_T1; + bus_request_type = BUS_MEM | BUS_OUT; + biu_begin_eu(); + biu_wait_for_write_finish(); + bus_request_type = 0; + + if ((addr >= 0xf0000) && (addr <= 0xfffff)) + last_addr = addr & 0xffff; +} + +/* Writes a word to the memory and advances the BIU. */ +void +writememw_vx0(uint32_t s, uint32_t a, uint16_t v) +{ + uint32_t addr = s + a; + + mem_seg = s; + mem_addr = a; + mem_data = v; + /* Do this, otherwise, the first half of the operation never happens. */ + if ((BUS_CYCLE == BUS_T4) && (biu_state == BIU_STATE_EU)) + BUS_CYCLE_T1; + if (is8086 && !(a & 1)) { + bus_request_type = BUS_MEM | BUS_OUT | BUS_WIDE; + biu_begin_eu(); + biu_wait_for_write_finish(); + } else { + bus_request_type = BUS_MEM | BUS_OUT | BUS_HIGH; + biu_begin_eu(); + biu_wait_for_write_finish(); + biu_cycle(); + biu_state = BIU_STATE_EU; + biu_state_length = 0; + bus_request_type = BUS_MEM | BUS_OUT; + biu_wait_for_write_finish(); + } + bus_request_type = 0; + + if ((addr >= 0xf0000) && (addr <= 0xfffff)) + last_addr = addr & 0xffff; +} + +void +writemem_vx0(uint32_t s, uint16_t v) +{ + if (opcode & 1) + writememw_vx0(s, cpu_state.eaaddr, v); + else + writememb_vx0(s, cpu_state.eaaddr, (uint8_t) (v & 0xff)); +} + +void +writememl_vx0(uint32_t s, uint32_t a, uint32_t v) +{ + writememw_vx0(s, a, v & 0xffff); + writememw_vx0(s, a + 2, v >> 16); +} + +void +writememq_vx0(uint32_t s, uint32_t a, uint64_t v) +{ + writememl_vx0(s, a, v & 0xffffffff); + writememl_vx0(s, a + 4, v >> 32); +} + +static void +pfq_write(void) +{ + uint16_t tempw; + /* Byte fetch on odd addres on 8086 to simulate the HL toggle. */ + int fetch_word = is8086 && !(pfq_ip & 1); + + if (fetch_word && (pfq_pos < (pfq_size - 1))) { + /* The 8086 fetches 2 bytes at a time, and only if there's at least 2 bytes + free in the queue. */ + tempw = pfq_in; + *(uint16_t *) &(pfq[pfq_pos]) = tempw; + pfq_ip = (pfq_ip + 2) & 0xffff; + pfq_pos += 2; + } else if (!fetch_word && (pfq_pos < pfq_size)) { + /* The 8088 fetches 1 byte at a time, and only if there's at least 1 byte + free in the queue. */ + if (pfq_pos >= 0) + pfq[pfq_pos] = pfq_in & 0xff; + pfq_ip = (pfq_ip + 1) & 0xffff; + pfq_pos++; + } + + if (pfq_pos >= pfq_size) + pfq_pos = pfq_size; +} + +uint8_t +biu_pfq_read(void) +{ + uint8_t temp; + + temp = pfq[0]; + for (int i = 0; i < (pfq_size - 1); i++) + pfq[i] = pfq[i + 1]; + pfq_pos--; + if (pfq_pos < 0) + pfq_pos = 0; + cpu_state.pc = (cpu_state.pc + 1) & 0xffff; + return temp; +} + +void +biu_resume_on_queue_read(void) +{ + if ((biu_next_state == BIU_STATE_IDLE) && (pfq_pos == 3)) + // pfq_switch_to_pf(is_nec ? 0 : ((biu_state == BIU_STATE_IDLE) ? 3 : 0)); + pfq_switch_to_pf(is_nec ? 0 : 3); +} + +/* Fetches a byte from the prefetch queue, or from memory if the queue has + been drained. + + Cycles: 1 If fetching from the queue; + (4 - (biu_cycles & 3)) If fetching from the bus - fetch into the queue; + 1 If fetching from the bus - delay. */ +uint8_t +biu_pfq_fetchb_common(void) +{ + uint8_t temp; + + if (biu_queue_preload) { + if (nx) + nx = 0; + + biu_queue_preload = 0; + return biu_preload_byte; + } + + if (pfq_pos > 0) { + if (biu_state == BIU_STATE_DELAY) { + while (biu_state == BIU_STATE_DELAY) + biu_cycle(); + } + + temp = biu_pfq_read(); + biu_resume_on_queue_read(); + } else { + /* Fill the queue. */ + while (pfq_pos == 0) + biu_cycle(); + + /* Fetch. */ + temp = biu_pfq_read(); + } + + do_cycle(); + return temp; +} + +/* The timings are above. */ +uint8_t +biu_pfq_fetchb(void) +{ + uint8_t ret; + + ret = biu_pfq_fetchb_common(); + return ret; +} + +/* Fetches a word from the prefetch queue, or from memory if the queue has + been drained. */ +uint16_t +biu_pfq_fetchw(void) +{ + uint16_t temp; + + temp = biu_pfq_fetchb_common(); + temp |= (biu_pfq_fetchb_common() << 8); + + return temp; +} + +uint16_t +biu_pfq_fetch(void) +{ + if (opcode & 1) + return biu_pfq_fetchw(); + else + return (uint16_t) biu_pfq_fetchb(); +} + +/* Adds bytes to the prefetch queue based on the instruction's cycle count. */ +static void +pfq_add(void) +{ + if ((biu_state == BIU_STATE_PF) && (pfq_pos < pfq_size)) + pfq_write(); +} + +void +biu_update_pc(void) +{ + pfq_ip = cpu_state.pc; + biu_queue_preload = 0; +} + +/* Clear the prefetch queue - called on reset and on anything that affects either CS or IP. */ +void +biu_queue_flush(void) +{ + pfq_pos = 0; + biu_update_pc(); + + fetch_suspended = 0; + + /* FLUSH command. */ + if ((biu_state == BIU_STATE_SUSP) || (biu_state == BIU_STATE_IDLE)) + pfq_resume(3); +} + +static void +biu_bus_wait_finish(void) +{ + while (BUS_CYCLE != BUS_T4) + biu_cycle(); +} + +void +biu_suspend_fetch(void) +{ + biu_state_length = 0; + fetch_suspended = 1; + + if (biu_state == BIU_STATE_PF) { + if (is_nec) + BUS_CYCLE_T1; + else { + biu_bus_wait_finish(); + biu_cycle(); + } + biu_state = BIU_STATE_IDLE; + biu_next_state = BIU_STATE_IDLE; + } else { + if (biu_state == BIU_STATE_EU) + BUS_CYCLE_T1; + biu_state = BIU_STATE_IDLE; + biu_next_state = BIU_STATE_IDLE; + } +} + +/* Memory refresh read - called by reads and writes on DMA channel 0. */ +void +refreshread(void) +{ + if (dma_state == DMA_STATE_IDLE) { + dma_state = DMA_STATE_TIMER; + dma_state_length = 1; + } +} diff --git a/src/cpu/vx0_biu.h b/src/cpu/vx0_biu.h new file mode 100644 index 0000000000..58e2ae257e --- /dev/null +++ b/src/cpu/vx0_biu.h @@ -0,0 +1,116 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 808x BIU emulation header. + * + * Authors: Andrew Jenner, + * Miran Grca, + * + * Copyright 2015-2020 Andrew Jenner. + * Copyright 2016-2020 Miran Grca. + */ +#ifndef EMU_808X_BIU_H +#define EMU_808X_BIU_H + +#define DEBUG_SEG 0xf000 +// #define DEBUG_SEG 0x0f3c +// #define DEBUG_SEG 0x1e1f +// #define DEBUG_SEG 0xf000 +// #define DEBUG_SEG 0xc800 +// #define DEBUG_SEG 0x0070 +// #define DEBUG_SEG 0x0291 +// #define DEBUG_SEG 0xefff +// #define DEBUG_SEG 0x15a2 + +// #define DEBUG_OFF_L 0x2c3b +// #define DEBUG_OFF_L 0xe182 +// #define DEBUG_OFF_L 0xf000 +// #define DEBUG_OFF_H 0xefff +// #define DEBUG_OFF_L 0x0000 +// #define DEBUG_OFF_H 0xffff +#define DEBUG_OFF_L 0xf300 +#define DEBUG_OFF_H 0xf3ff + +#define BUS_OUT 1 +#define BUS_HIGH 2 +#define BUS_WIDE 4 +#define BUS_CODE 8 +#define BUS_IO 16 +#define BUS_MEM 32 +#define BUS_PIC 64 +#define BUS_ACCESS_TYPE (BUS_CODE | BUS_IO | BUS_MEM | BUS_PIC) + +#undef readmemb +#undef readmemw +#undef readmeml +#undef readmemq + +enum { + BUS_T1 = 0, + BUS_T2, + BUS_T3, + BUS_T4 +}; + +enum { + BIU_STATE_IDLE, + BIU_STATE_SUSP, + BIU_STATE_DELAY, + BIU_STATE_RESUME, + BIU_STATE_WAIT, + BIU_STATE_PF, + BIU_STATE_EU +}; + +enum { + DMA_STATE_IDLE, + DMA_STATE_TIMER, + DMA_STATE_DREQ, + DMA_STATE_HRQ, + DMA_STATE_HLDA, + DMA_STATE_OPERATING +}; + +/* Temporary BIU externs - move to 808x_biu.h. */ +extern void biu_resume_on_queue_read(void); +extern void wait(int c); +extern void biu_reset(void); +extern void cpu_io_vx0(int bits, int out, uint16_t port); +extern void biu_state_set_eu(void); +extern uint8_t readmemb_vx0(uint32_t s, uint16_t a); +extern uint16_t readmemw_vx0(uint32_t s, uint16_t a); +extern uint16_t readmem_vx0(uint32_t s); +extern uint32_t readmeml_vx0(uint32_t s, uint16_t a); +extern uint64_t readmemq_vx0(uint32_t s, uint16_t a); +extern void writememb_vx0(uint32_t s, uint32_t a, uint8_t v); +extern void writememw_vx0(uint32_t s, uint32_t a, uint16_t v); +extern void writemem_vx0(uint32_t s, uint16_t v); +extern void writememl_vx0(uint32_t s, uint32_t a, uint32_t v); +extern void writememq_vx0(uint32_t s, uint32_t a, uint64_t v); +extern uint8_t biu_pfq_read(void); +extern uint8_t biu_pfq_fetchb_common(void); +extern uint8_t biu_pfq_fetchb(void); +extern uint16_t biu_pfq_fetchw(void); +extern uint16_t biu_pfq_fetch(void); +extern void biu_update_pc(void); +extern void biu_queue_flush(void); +extern void biu_suspend_fetch(void); +extern void biu_begin_eu(void); +extern void biu_wait_for_read_finish(void); + +extern uint8_t biu_preload_byte; + +extern int nx; + +extern int schedule_fetch; +extern int in_lock; +extern int bus_request_type; +extern int pic_data; +extern int biu_queue_preload; + +#endif /*EMU_808X_BIU_H*/ diff --git a/src/cpu/x86.c b/src/cpu/x86.c index 38e50a4887..a19ac440a0 100644 --- a/src/cpu/x86.c +++ b/src/cpu/x86.c @@ -367,8 +367,12 @@ reset_common(int hard) } else device_reset_all(DEVICE_SOFTRESET); - if (!is286) - reset_808x(hard); + if (!is286) { + if (is_nec) + reset_vx0(hard); + else + reset_808x(hard); + } in_lock = 0; diff --git a/src/cpu/x86.h b/src/cpu/x86.h index ccfeadea05..c0140520f0 100644 --- a/src/cpu/x86.h +++ b/src/cpu/x86.h @@ -37,6 +37,7 @@ extern uint8_t opcode; extern uint8_t flags_p; extern uint8_t znptable8[256]; +extern uint16_t last_addr; extern uint16_t zero; extern uint16_t oldcs; extern uint16_t lastcs; @@ -44,6 +45,7 @@ extern uint16_t lastpc; extern uint16_t *mod1add[2][8]; extern uint16_t znptable16[65536]; +extern int pfq_pos; extern int x86_was_reset; extern int trap; extern int codegen_flat_ss; diff --git a/src/cpu/x87_ops.h b/src/cpu/x87_ops.h index 4d099885a2..f74e5e91ad 100644 --- a/src/cpu/x87_ops.h +++ b/src/cpu/x87_ops.h @@ -551,7 +551,11 @@ static int FPU_ILLEGAL_a16(UNUSED(uint32_t fetchdat)) { geteaw(); +#ifdef FPU_NEC + do_cycles(timing_rr); +#else wait_cycs(timing_rr, 0); +#endif return 0; } #else diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index 417beea627..68955e07d0 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -7,7 +7,11 @@ opFI(uint32_t fetchdat) cpu_state.npxc &= ~0x80; if (rmdat == 0xe1) cpu_state.npxc |= 0x80; +#ifdef FPU_NEC + do_cycles(3); +#else wait_cycs(3, 0); +#endif return 0; } #else diff --git a/src/cpu/x87_ops_sf.h b/src/cpu/x87_ops_sf.h index adbaa20039..722d86435f 100644 --- a/src/cpu/x87_ops_sf.h +++ b/src/cpu/x87_ops_sf.h @@ -354,7 +354,11 @@ sf_FI(uint32_t fetchdat) fpu_state.cwd &= ~FPU_SW_Summary; if (rmdat == 0xe1) fpu_state.cwd |= FPU_SW_Summary; +#ifdef FPU_NEC + do_cycles(3); +#else wait_cycs(3, 0); +#endif return 0; } #else From 8b1e1ab1bffa065c9161bef52c7321277b4b04c3 Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 28 Jan 2026 08:46:03 +0100 Subject: [PATCH 58/58] Bump version to 6.0, I think we have accumulated enough features to warrant that. --- CMakeLists.txt | 2 +- debian/changelog | 4 ++-- src/unix/assets/86Box.spec | 6 +++--- src/unix/assets/net.86box.86Box.metainfo.xml | 2 +- vcpkg.json | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b64902c122..b503b3e390 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ if(MUNT_EXTERNAL) endif() project(86Box - VERSION 5.4 + VERSION 6.0 DESCRIPTION "Emulator of x86-based systems" HOMEPAGE_URL "https://86box.net" LANGUAGES C CXX) diff --git a/debian/changelog b/debian/changelog index c0c4bf945e..72e246145a 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -86box (5.4) UNRELEASED; urgency=medium +86box (6.0) UNRELEASED; urgency=medium * Bump release. - -- Jasmine Iwanek Tue, 23 Dec 2025 00:27:45 +0100 + -- Jasmine Iwanek Wed, 28 Jan 2026 08:45:23 +0100 diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index a189a5f41a..aefac7a4f1 100644 --- a/src/unix/assets/86Box.spec +++ b/src/unix/assets/86Box.spec @@ -12,10 +12,10 @@ # After a successful build, you can install the RPMs as follows: # sudo dnf install RPMS/$(uname -m)/86Box-3* RPMS/noarch/86Box-roms* -%global romver 5.4 +%global romver 6.0 Name: 86Box -Version: 5.4 +Version: 6.0 Release: 1%{?dist} Summary: Classic PC emulator License: GPLv2+ @@ -121,5 +121,5 @@ popd %{_datadir}/%{name}/roms %changelog -* Sat Aug 31 Jasmine Iwanek 5.4-1 +* Sat Aug 31 Jasmine Iwanek 6.0-1 - Bump release diff --git a/src/unix/assets/net.86box.86Box.metainfo.xml b/src/unix/assets/net.86box.86Box.metainfo.xml index c6a612a4c1..4fdfe9c2a3 100644 --- a/src/unix/assets/net.86box.86Box.metainfo.xml +++ b/src/unix/assets/net.86box.86Box.metainfo.xml @@ -11,7 +11,7 @@ net.86box.86Box.desktop - + diff --git a/vcpkg.json b/vcpkg.json index 4c0d502ef1..6a4f6376cb 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,6 +1,6 @@ { "name": "86box", - "version-string": "5.4", + "version-string": "6.0", "homepage": "https://86box.net/", "documentation": "https://86box.readthedocs.io/", "license": "GPL-2.0-or-later",