diff --git a/.ci/AppImageBuilder.yml b/.ci/AppImageBuilder.yml index 61bbcba95e4..ad0bc904c6b 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 a5b20f2aa63..81c69a20ac3 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 @@ -377,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 @@ -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 + 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,17 @@ 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 +rm -f mdsx/src/*.a +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 +965,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 @@ -1081,7 +1097,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 @@ -1136,6 +1153,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 @@ -1257,7 +1277,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. diff --git a/.ci/dependencies_msys.txt b/.ci/dependencies_msys.txt index b6c0979e27d..70d00a3f734 100644 --- a/.ci/dependencies_msys.txt +++ b/.ci/dependencies_msys.txt @@ -15,3 +15,4 @@ qt5-translations vulkan-headers libsndfile libserialport +make diff --git a/CMakeLists.txt b/CMakeLists.txt index 667df522148..b503b3e3909 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) @@ -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/debian/changelog b/debian/changelog index c0c4bf945ed..72e246145ad 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/86box.c b/src/86box.c index ce9a3d96ea1..24e8be26ab9 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,16 +736,12 @@ 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 | ((s == NULL) ? MBX_INFO : MBX_WARNING), p); + ui_msgbox(MBX_ANSI | MBX_INFO, p); #else - if (s == NULL) - always_log("%s", p); - else - ui_msgbox(MBX_ANSI | MBX_WARNING, p); + always_log("%s", p); #endif } @@ -845,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; @@ -1708,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/chipset/ali1435.c b/src/chipset/ali1435.c index aebd10f32af..6619e033c1f 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 96ebd4a3d11..fdf0697ec92 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 1603dbca4a1..b57fe160633 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 1506d880abb..02fd51c0baa 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 8ef8e6a2049..3d5ddf603f6 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 95602496c34..217c1b865af 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 13fed304b6a..16625f3a1e4 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 daa55c72c98..67e2ae06995 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 18f4ee66a90..48627e39b5d 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 34cc6a62f72..cb793179a56 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 c6f6486d1e3..9f781486996 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); @@ -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/chipset/intel_sio.c b/src/chipset/intel_sio.c index 739785acb73..c28fa5471e1 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/laserxt.c b/src/chipset/laserxt.c index a5308e2f014..bf2636b9174 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/chipset/opti822.c b/src/chipset/opti822.c index 2f416a1c27f..2029a6b40cf 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 38fcfe717ae..c22f798afc9 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 02e86a98a83..824f1f3386b 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 525fe65980a..ea54a407b26 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 d814e0f749d..48cbe976542 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 564243c68c8..2610ea88fac 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 f2c1941d49b..a04f016331b 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 e932ff6ca68..5eb3b518d91 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 56eca8268df..e78a68c20b0 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 3725394c3d3..7350f50584e 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 cb69ce6a8d4..1be55de8873 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 55901b32ea5..ae62da16642 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 3236bbbbe89..b4646ba04f4 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 a476b9b9900..a5883791ec9 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 3daeec85b07..467509fb6a3 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/vl82c480.c b/src/chipset/vl82c480.c index 2ab17eadd0e..cf368275426 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(); diff --git a/src/chipset/vl82c59x.c b/src/chipset/vl82c59x.c index 69b6ebf1d69..30cc63065f8 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/cpu/808x.c b/src/cpu/808x.c index 4e2e830d0e7..7908160e80d 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 dc7f5ac1106..7eadb94faa8 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 8d00da512c9..e0868861dcb 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(); @@ -1897,7 +1899,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; diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 865e76ffb28..8e74bc78aeb 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 00000000000..bd1a8da201c --- /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 00000000000..b52b142458a --- /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 00000000000..58e2ae257e7 --- /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 38e50a48872..a19ac440a0a 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 ccfeadea057..c0140520f02 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 4d099885a29..f74e5e91ade 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 417beea627f..68955e07d0c 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 adbaa200390..722d86435f5 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 diff --git a/src/device/hasp.c b/src/device/hasp.c index ea8b9b413e4..f4b6bc0ad04 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(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 f7cc6eda0ea..a7fb5ac2da8 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 }, @@ -56,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 } @@ -83,50 +84,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 +139,43 @@ 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_inst((device_t *) lpt_devices[lpt_ports[i].device].device, i + 1); } } +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), + 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) +{ + 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; + 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 +960,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 +1039,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/device/pci_bridge.c b/src/device/pci_bridge.c index d9aeeffb657..0a323484a34 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 b5fc077b80c..6ffb62c86db 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, 2, vfio_config_readw(0, 0x04, 2, dev) & ~0x0407, dev); } static void @@ -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/disk/hdc_ide.c b/src/disk/hdc_ide.c index 7b2b7681629..56548766ab7 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; @@ -1721,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))) @@ -1786,7 +1783,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 +2349,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; diff --git a/src/disk/hdc_ide_cmd640.c b/src/disk/hdc_ide_cmd640.c index ea2a195d947..44e488df4ab 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 333cd5e30d5..9cd50e8719c 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 56568cc2c68..7559041b8b8 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 25ee16d1094..cb4d9177887 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/chipset.h b/src/include/86box/chipset.h index 64b5bd88f5d..4ded831bde5 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/lpt.h b/src/include/86box/lpt.h index 61c95094f92..fe5442379fd 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,21 @@ 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(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/machine.h b/src/include/86box/machine.h index 92b448eebe8..caf929c1946 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 *); @@ -1404,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 */ @@ -1475,6 +1482,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/include/86box/network.h b/src/include/86box/network.h index 0642c3f53cf..2c91a6d9f5f 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/nmc93cxx.h b/src/include/86box/nmc93cxx.h index dd02b2d0616..b8c9d61b64d 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/include/86box/nvr.h b/src/include/86box/nvr.h index 4d187b78534..9d6d789238f 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/include/86box/pci.h b/src/include/86box/pci.h index a721db005e4..f5f5aee04f2 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/include/86box/prt_devs.h b/src/include/86box/prt_devs.h index d136d9d933b..34318294614 100644 --- a/src/include/86box/prt_devs.h +++ b/src/include/86box/prt_devs.h @@ -1,15 +1,9 @@ #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; -#ifdef USE_PCL -extern const lpt_device_t lpt_prt_pcl_device; -extern const device_t prt_pcl_device; -#endif +extern const device_t lpt_prt_text_device; +extern const device_t lpt_prt_escp_device; +extern const device_t lpt_prt_ps_device; +extern const device_t lpt_prt_pcl_device; #endif /*EMU_PRT_DEVS_H*/ diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index dddb216f68b..d0cd2554777 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/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 713ab09c05c..cbd0cdec5fd 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 } } }, diff --git a/src/machine/m_at_socket370.c b/src/machine/m_at_socket370.c index 6627c709719..6602f2aedb1 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 } } }, diff --git a/src/machine/m_at_socket7.c b/src/machine/m_at_socket7.c index 7261e2616ae..24b0b9e8447 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/m_v86p.c b/src/machine/m_v86p.c index 1265173458c..d30d9c8a6e8 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/m_xt.c b/src/machine/m_xt.c index 81c9eba7280..6da39d9971b 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; diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 2cd3db8a55d..762c4410ec4 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, @@ -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)", @@ -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/mem/catalyst_flash.c b/src/mem/catalyst_flash.c index da9bfc2492d..bed0384af72 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 50e8016ce57..266bd78351e 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/nmc93cxx.c b/src/mem/nmc93cxx.c index 17d97591edb..bdbc46c92f3 100644 --- a/src/mem/nmc93cxx.c +++ b/src/mem/nmc93cxx.c @@ -6,269 +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); } } + +#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 #else -# define nmc93cxx_eeprom_log(lvl, fmt, ...) +# define nmc93cxx_eeprom_log(dev, lvl, fmt, ...) #endif +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, (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, (size_t) dev->cells * ((size_t) 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) { - if (UNLIKELY(eeprom == NULL)) - return NULL; + 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/mem/sst_flash.c b/src/mem/sst_flash.c index 024bcf6a57d..656ed225b37 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); } } } diff --git a/src/network/net_ne2000.c b/src/network/net_ne2000.c index 3e2e7dd38a1..97990538599 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); @@ -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; @@ -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_pcap.c b/src/network/net_pcap.c index e0c6804f41f..abfd9dea860 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_pcnet.c b/src/network/net_pcnet.c index 2d9aa88bbf6..e4cad2552ec 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_plip.c b/src/network/net_plip.c index 36df49153c3..f61c046461d 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(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/network/net_rtl8139.c b/src/network/net_rtl8139.c index 9cc52417fd9..0daf25a6a30 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; @@ -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_slirp.c b/src/network/net_slirp.c index 4f61a55a884..c7243baacb2 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 5fc3a209178..d29513f7468 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_tulip.c b/src/network/net_tulip.c index 298cda23292..b5219cf2375 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); } @@ -1180,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; @@ -1299,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; @@ -1640,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/network/net_vde.c b/src/network/net_vde.c index 4f8d5c21f7d..6e82d466953 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 diff --git a/src/nvr_at.c b/src/nvr_at.c index 07588fb01b7..11b5ffc4572 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -289,21 +289,22 @@ #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_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; uint8_t cent; uint8_t def; - uint8_t flags; uint8_t read_addr; uint8_t wp_0d; uint8_t wp_32; @@ -317,6 +318,8 @@ typedef struct local_t { int16_t count; int16_t state; + uint16_t flags; + uint16_t addr[8]; int32_t smi_enable; @@ -576,6 +579,10 @@ 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 == 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; if ((reg >= 0xb8) && (reg <= 0xbf) && local->wp[1]) @@ -825,6 +832,34 @@ 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 == 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]; + 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 +892,20 @@ nvr_read(uint16_t addr, void *priv) ret = nvr->regs[local->addr[addr_id]]; break; + 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]]; + break; + default: if (!(local->lock[local->addr[addr_id]] & 0x02)) ret = nvr->regs[local->addr[addr_id]]; @@ -1173,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_1995_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: @@ -1460,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, diff --git a/src/pci.c b/src/pci.c index 16e8cdb4f01..9d08a9e08cd 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 bceb58c22da..e5395bed878 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/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index 0efb2aec243..1b4d9c0c51f 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 a240729714d..2a50ae54f17 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(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 adf57a52376..29ae78feb83 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; - pc_timer_t pulse_timer; - pc_timer_t timeout_timer; + char data; - 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 printer_path[260]; + char filename[260]; - char printer_path[260]; + char buffer[POSTSCRIPT_BUFFER_LENGTH]; - char filename[260]; + uint8_t ctrl; + uint8_t pcl_escape; - char buffer[POSTSCRIPT_BUFFER_LENGTH]; - size_t buffer_pos; + uint16_t pjl_command_start; + + 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++] = "-lPCL5E"; + 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,92 +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_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; - } + 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] = 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; - if (dev->data == 0x0e) { - 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->buffer_pos > 2) - write_buffer(dev, true); + /* Wipe the slate clean so that there won't be a bogus empty page output to PDF. */ + dev->pending = false; + ret = 1; + } + break; + } - return; - } - 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) - dev->pjl = true; - 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; + } } } @@ -460,34 +519,39 @@ 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; - /* Try loading the DLL. */ - ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); + 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"); + + 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; + } } } @@ -506,36 +570,40 @@ ps_init(void *lpt) return dev; } -#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; - /* Try loading the DLL. */ - ghostscript_handle = dynld_module(PATH_GHOSTPCL_DLL, ghostscript_imports); + 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"); + + 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; + } } } @@ -553,7 +621,6 @@ pcl_init(void *lpt) return dev; } -#endif static void ps_close(void *priv) @@ -574,36 +641,75 @@ 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 +// 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", + .flags = DEVICE_LPT, + .local = 0, + .init = ps_init, + .close = ps_close, + .reset = NULL, + .available = NULL, + .speed_changed = NULL, + .force_redraw = NULL, + .config = lpt_prt_ps_config }; -#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 PCL 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 = lpt_prt_pcl_config }; -#endif diff --git a/src/printer/prt_text.c b/src/printer/prt_text.c index af601af75d0..ad49bc56f3d 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(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/qt/languages/86box.pot b/src/qt/languages/86box.pot index c5d1d25144d..c62c18ea84a 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 ad9dd6eb11d..0c1c8ac893a 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 bed51f2610a..1df82475fa3 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-21 07:40+0000\n" "Last-Translator: David Hrdlička \n" "Language-Team: Czech \n" "Language: cs-CZ\n" @@ -3016,10 +3016,13 @@ msgid "&Allow recompilation" msgstr "&Povolit rekompilaci" msgid "&Fast forward" -msgstr "" +msgstr "&Zrychlit" msgid "Fast forward" -msgstr "" +msgstr "Zrychlit" msgid "To change the system directory, stop all running machines." -msgstr "" +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 38e82986177..f377fcad0f0 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 9243c24fb23..6933075a563 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,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/es-ES.po b/src/qt/languages/es-ES.po index 3d339efd01e..4f34c34f552 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 fd6add6960a..a5f36d2d48f 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 2e1422a08cd..42f1a8f406b 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 b3d9a68f188..32aaf1cf7e9 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 f4d16bf860e..f46d09159a5 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 2a7809a47f4..027b052047d 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 0318e85f322..cd186260b3d 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 e31768305d8..88679fdd352 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 3d056a2ea20..63dcd239b3b 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 20317c9eccc..e67ada685ef 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 31875d7bab0..5ffbc2c72a4 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 f18eb8f1ab8..8f0f55caf4e 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 6102dceeda4..9ca679356db 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 a112005da81..a5570faebbb 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 64cc6e7eb35..dfe0acbcde6 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 f4923591915..eb76331684b 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 aad11ffda18..510fd82f3c5 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,13 @@ 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." + +msgid "Raw" +msgstr "Ham" diff --git a/src/qt/languages/uk-UA.po b/src/qt/languages/uk-UA.po index 7fd0d0b3325..d1964e647f4 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 b2c7491a105..64d00e21038 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 a960d8b2d35..7e98480cd9c 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 "重大性能影响" @@ -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 0bdcd215a0f..78365a9113b 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/qt/qt_defs.hpp b/src/qt/qt_defs.hpp new file mode 100644 index 00000000000..1190c0ed180 --- /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 diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 229e9f788df..f6195389c67 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(); @@ -1216,16 +1218,16 @@ 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); - QObject::connect(chkbox, &QCheckBox::stateChanged, [](int state) { + QObject::connect(chkbox, &QCheckBox::CHECK_STATE_CHANGED, [](int state) { confirm_reset = (state == Qt::CheckState::Unchecked); }); questionbox.exec(); - if (questionbox.result() == QDialog::Accepted) { + if (questionbox.clickedButton() == no_reset_button) { confirm_reset = true; return; } diff --git a/src/qt/qt_settings.cpp b/src/qt/qt_settings.cpp index 3920aaeb269..312b48996f1 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_settingsports.cpp b/src/qt/qt_settingsports.cpp index b1155629dbd..232822201a1 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++; diff --git a/src/qt/qt_vulkanwindowrenderer.cpp b/src/qt/qt_vulkanwindowrenderer.cpp index c27d382a50b..41f913a87f5 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) && !defined(Q_OS_WINDOWS) + 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) { diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index daeb0a3e4c2..754750b22d6 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 bc3ecec0ba3..eef94c916ef 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 11793f5a936..327d35cbb1c 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -1997,7 +1998,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 +2010,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,23 +2088,21 @@ 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; - 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; } @@ -2297,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/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 23c4863c765..9a4cb3c6ff8 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 9ee003689ea..d4490ac2390 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/sound/snd_lpt_dac.c b/src/sound/snd_lpt_dac.c index 33b197230ce..77271ed8d77 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(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 5ea0048f475..6fac66b6e86 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(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 }; diff --git a/src/unix/assets/86Box.spec b/src/unix/assets/86Box.spec index a189a5f41ae..aefac7a4f1f 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 c6a612a4c15..4fdfe9c2a33 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/src/video/vid_8514a.c b/src/video/vid_8514a.c index d521c07d5a7..872743b72e2 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,9 +289,24 @@ 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)) - monoxfer = val; - else { + 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; if (val & 0x04) @@ -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; @@ -893,8 +907,9 @@ 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 { ibm8514_accel_out_pixtrans(svga, port, temp, len); + } } } break; @@ -977,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; } @@ -1066,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) { @@ -1225,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); @@ -1296,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); + } } } } @@ -1406,12 +1427,42 @@ 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, 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) - dev->accel.output = 1; + if (dev->accel.cmd & 0x08) { + 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; + } + } + } } } dev->force_busy = 1; @@ -1424,174 +1475,258 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->force_busy2 = 1; dev->data_available = 1; dev->data_available2 = 1; - return; + return; /*Wait for data from CPU*/ } } 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 & 0x02) - ibm8514_log("Line Draw Vector Single pixtrans=%04x, count=%d.\n", mix_dat, count); + 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)) { - 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; + } + + 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 { + 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; + } - 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.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; + if (!dev->accel.sy) { + dev->force_busy = 0; + dev->force_busy2 = 0; + dev->fifo_idx = 0; + dev->accel.cmd_back = 1; + 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; + 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; - } + 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 (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; + 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; } - break; - } - - if (dev->accel.output) - mix_dat >>= 1; - else { - mix_dat <<= 1; - mix_dat |= 1; - } - if (dev->bpp) - cpu_dat >>= 16; - else - cpu_dat >>= 8; + 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++; - 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; + 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; - } + default: + break; + } - dev->accel.sy--; + if (dev->accel.cmd & 0x02) + mix_dat >>= 1; + else { + mix_dat <<= 1; + mix_dat |= 1; + } + dev->accel.sy--; + dev->accel.x_count++; + } } - dev->accel.x_count = 0; - dev->accel.output = 0; } else { /*Bresenham Line*/ if (pixcntl == 1) { dev->accel.temp_cnt = 8; @@ -1817,6 +1952,7 @@ 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.odd_in = 0; @@ -1832,6 +1968,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) @@ -1842,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 { @@ -1885,7 +2048,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } } } - 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; @@ -1905,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; @@ -1933,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); + } } } } @@ -1970,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); @@ -2039,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; @@ -2056,100 +2201,66 @@ 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) && (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); + } } } } @@ -2159,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 { @@ -2178,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; @@ -2198,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; @@ -2844,6 +2951,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; @@ -2851,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; } @@ -2900,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); @@ -2956,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); } } @@ -2979,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 { @@ -2998,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) { @@ -3021,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; @@ -3252,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) && @@ -3303,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); } } diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index ceaf4224b84..8ce13f14d33 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 81abadd5666..fff9bce3ec8 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.*/ @@ -7087,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; @@ -7166,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 0a41bec2d5a..d14e92ec137 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 ef48207e15f..2cd6c416201 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 4161e223e82..7979758ef27 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_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_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] & CIRRUS_SR7_BPP_SVGA)) { + 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)) + 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)) + 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)) + return svga_readl(addr, svga); + if (gd54xx->countminusone && gd54xx->blt.ms_is_dest && !(gd54xx->blt.status & CIRRUS_BLT_PAUSED)) { ret = gd54xx_read(addr, svga); @@ -3934,7 +3959,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 +4071,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 4abb9a76768..18d6b4575d3 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 07b0869f797..449b21866b8 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 101d3ae8bf5..37ade5ad1a0 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; @@ -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; } } } @@ -1999,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) { @@ -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; @@ -6698,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); @@ -10963,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; @@ -11052,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; @@ -12199,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; diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index abeba064ec2..b53dd5e8cc5 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 28c02363c73..f91fc3f9612 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)) { @@ -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 72a57e66c7b..78aba3cadd6 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 f914c7e866e..f6f0476ad02 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 diff --git a/vcpkg.json b/vcpkg.json index 4c0d502ef14..6a4f6376cb8 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",